LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

C# 关于AD域的操作

admin
2021年6月26日 23:59 本文热度 3456

前段时间公司说让系统可以进行对AD域的操作,包括创建用户。于是上网查资料,了解何为AD域。还不知道的这边请https://www.cnblogs.com/cnjavahome/p/9029665.html。

网上有很多提供对AD域操作的帮助类,简称ADHelper.cs,等会我也发一个。使用网上的帮助类的时候我遇到几个问题。这就是我为什么写这个随笔的原因。

问题1:创建用户的时候提示以下错误。

有几种原因:密码错误,不满足密码复杂度(长度至少7,且含有英文数字特殊符号),对账号启用的时候也会报这个错误。

  public static void EnableUser(DirectoryEntry de)
        {
            try
            {
                impersonate.BeginImpersonate();
                de.Properties["userAccountControl"].Value = ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_NORMAL_ACCOUNT | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_TRUSTED_FOR_DELEGATION | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD;
                de.CommitChanges();
                impersonate.StopImpersonate();
                de.Close();
            }
            catch (Exception ex)
            {
                throw;
            }
        }

这个方法在本机的时候运行可以,但是到了客户测试那边还是报以上的错误,而且这个错误百度找不到,只好google,谁叫我不懂呢。查找了好久好久好久……发现了一个新的方式去启用这个方法就是这样:

public static void EnableUser(string commonName)
        {
            try
            {
                //DomainName:填写域名, Administrator表示登录账户,123456密码。
                PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, DomainName, "Administrator", "123456");
                UserPrincipal userPrincipal = UserPrincipal.FindByIdentity(principalContext,commonName);
                userPrincipal.Enabled = true;
                //如果是禁用这里就改成false
                userPrincipal.Save();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
        }

好了这里的启用错误改好了。

问题2:有空的时候加上去吧

下面放个我的ADHelper:

   1 using System;
   2 using System.DirectoryServices;
   3 using System.DirectoryServices.AccountManagement;
   4 using System.Runtime.InteropServices;
   5 using System.Security.Principal;
   6 
   7 
   8 
   9 namespace SystemFrameworks.Helper
  10 {
  11 
  12     /// 
  13 
  14     /// 活动目录辅助类。封装一系列活动目录操作相关的方法。
  15 
  16     /// 
  17 
  18     public sealed class ADHelper
  19     {
  20 
  21         /// 
  22 
  23         /// 域名
  24 
  25         /// 
  26 
  27         private static string DomainName = "TEST.COM";
  28 
  29         /// 
  30 
  31         /// LDAP 地址
  32 
  33         /// 
  34 
  35         private static string LDAPDomain = "CN=Schema,CN=Configuration,DC=test,DC=com";
  36 
  37         /// 
  38 
  39         /// LDAP绑定路径
  40 
  41         /// 
  42 
  43         private static string ADPath = "LDAP://test.com";
  44 
  45         /// 
  46 
  47         /// 登录帐号
  48 
  49         /// 
  50 
  51         private static string ADUser = "Administrator";
  52 
  53         /// 
  54 
  55         /// 登录密码
  56 
  57         /// 
  58 
  59         private static string ADPassword = "123456";
  60 
  61         /// 
  62 
  63         /// 扮演类实例
  64 
  65         /// 
  66 
  67         private static IdentityImpersonation impersonate = new IdentityImpersonation(ADUser, ADPassword, DomainName);
  68 
  69 
  70 
  71         /// 
  72 
  73         /// 用户登录验证结果
  74 
  75         /// 
  76 
  77         public enum LoginResult
  78         {
  79 
  80             /// 
  81 
  82             /// 正常登录
  83 
  84             /// 
  85 
  86             LOGIN_USER_OK = 0,
  87 
  88             /// 
  89 
  90             /// 用户不存在
  91 
  92             /// 
  93 
  94             LOGIN_USER_DOESNT_EXIST,
  95 
  96             /// 
  97 
  98             /// 用户帐号被禁用
  99 
 100             /// 
 101 
 102             LOGIN_USER_ACCOUNT_INACTIVE,
 103 
 104             /// 
 105 
 106             /// 用户密码不正确
 107 
 108             /// 
 109 
 110             LOGIN_USER_PASSWORD_INCORRECT
 111 
 112         }
 113 
 114 
 115 
 116         /// 
 117 
 118         /// 用户属性定义标志
 119 
 120         /// 
 121 
 122         public enum ADS_USER_FLAG_ENUM
 123         {
 124 
 125             /// 
 126 
 127             /// 登录脚本标志。如果通过 ADSI LDAP 进行读或写操作时,该标志失效。如果通过 ADSI WINNT,该标志为只读。
 128 
 129             /// 
 130 
 131             ADS_UF_SCRIPT = 0X0001,
 132 
 133             /// 
 134 
 135             /// 用户帐号禁用标志
 136 
 137             /// 
 138 
 139             ADS_UF_ACCOUNTDISABLE = 0X0002,
 140 
 141             /// 
 142 
 143             /// 主文件夹标志
 144 
 145             /// 
 146 
 147             ADS_UF_HOMEDIR_REQUIRED = 0X0008,
 148 
 149             /// 
 150 
 151             /// 过期标志
 152 
 153             /// 
 154 
 155             ADS_UF_LOCKOUT = 0X0010,
 156 
 157             /// 
 158 
 159             /// 用户密码不是必须的
 160 
 161             /// 
 162 
 163             ADS_UF_PASSWD_NOTREQD = 0X0020,
 164 
 165             /// 
 166 
 167             /// 密码不能更改标志
 168 
 169             /// 
 170 
 171             ADS_UF_PASSWD_CANT_CHANGE = 0X0040,
 172 
 173             /// 
 174 
 175             /// 使用可逆的加密保存密码
 176 
 177             /// 
 178 
 179             ADS_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 0X0080,
 180 
 181             /// 
 182 
 183             /// 本地帐号标志
 184 
 185             /// 
 186 
 187             ADS_UF_TEMP_DUPLICATE_ACCOUNT = 0X0100,
 188 
 189             /// 
 190 
 191             /// 普通用户的默认帐号类型
 192 
 193             /// 
 194 
 195             ADS_UF_NORMAL_ACCOUNT = 0X0200,
 196 
 197             /// 
 198 
 199             /// 跨域的信任帐号标志
 200 
 201             /// 
 202 
 203             ADS_UF_INTERDOMAIN_TRUST_ACCOUNT = 0X0800,
 204 
 205             /// 
 206 
 207             /// 工作站信任帐号标志
 208 
 209             /// 
 210 
 211             ADS_UF_WORKSTATION_TRUST_ACCOUNT = 0x1000,
 212 
 213             /// 
 214 
 215             /// 服务器信任帐号标志
 216 
 217             /// 
 218 
 219             ADS_UF_SERVER_TRUST_ACCOUNT = 0X2000,
 220 
 221             /// 
 222 
 223             /// 密码永不过期标志
 224 
 225             /// 
 226 
 227             ADS_UF_DONT_EXPIRE_PASSWD = 0X10000,
 228 
 229             /// 
 230 
 231             /// MNS 帐号标志
 232 
 233             /// 
 234 
 235             ADS_UF_MNS_LOGON_ACCOUNT = 0X20000,
 236 
 237             /// 
 238 
 239             /// 交互式登录必须使用智能卡
 240 
 241             /// 
 242 
 243             ADS_UF_SMARTCARD_REQUIRED = 0X40000,
 244 
 245             /// 
 246 
 247             /// 当设置该标志时,服务帐号(用户或计算机帐号)将通过 Kerberos 委托信任
 248 
 249             /// 
 250 
 251             ADS_UF_TRUSTED_FOR_DELEGATION = 0X80000,
 252 
 253             /// 
 254 
 255             /// 当设置该标志时,即使服务帐号是通过 Kerberos 委托信任的,敏感帐号不能被委托
 256 
 257             /// 
 258 
 259             ADS_UF_NOT_DELEGATED = 0X100000,
 260 
 261             /// 
 262 
 263             /// 此帐号需要 DES 加密类型
 264 
 265             /// 
 266 
 267             ADS_UF_USE_DES_KEY_ONLY = 0X200000,
 268 
 269             /// 
 270 
 271             /// 不要进行 Kerberos 预身份验证
 272 
 273             /// 
 274 
 275             ADS_UF_DONT_REQUIRE_PREAUTH = 0X4000000,
 276 
 277             /// 
 278 
 279             /// 用户密码过期标志
 280 
 281             /// 
 282 
 283             ADS_UF_PASSWORD_EXPIRED = 0X800000,
 284 
 285             /// 
 286 
 287             /// 用户帐号可委托标志
 288 
 289             /// 
 290 
 291             ADS_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 0X1000000
 292 
 293         }
 294 
 295 
 296 
 297         public ADHelper()
 298         {
 299 
 300             //
 301 
 302         }
 303 
 304 
 305 
 306         #region GetDirectoryObject
 307 
 308 
 309 
 310         /// 
 311 
 312         /// 获得DirectoryEntry对象实例,以管理员登陆AD
 313 
 314         /// 
 315 
 316         /// 
 317 
 318         private static DirectoryEntry GetDirectoryObject()
 319         {
 320 
 321             DirectoryEntry entry = new DirectoryEntry(ADPath, ADUser, ADPassword, AuthenticationTypes.Secure);
 322 
 323             return entry;
 324 
 325         }
 326         public static bool Ver()
 327         {
 328             try
 329             {
 330                 DirectoryEntry de = GetDirectoryObject();
 331                 de.RefreshCache();
 332                 return true;
 333             }
 334             catch (Exception ex)
 335             {
 336                 throw;
 337             }
 338             return false;
 339         }
 340 
 341 
 342 
 343         /// 
 344 
 345         /// 根据指定用户名和密码获得相应DirectoryEntry实体
 346 
 347         /// 
 348 
 349         /// 
 350 
 351         /// 
 352 
 353         /// 
 354 
 355         private static DirectoryEntry GetDirectoryObject(string userName, string password)
 356         {
 357 
 358             DirectoryEntry entry = new DirectoryEntry(ADPath, userName, password, AuthenticationTypes.None);
 359 
 360             return entry;
 361 
 362         }
 363 
 364 
 365 
 366         /// 
 367 
 368         /// i.e. /CN=Users,DC=creditsights, DC=cyberelves, DC=Com
 369 
 370         /// 
 371 
 372         /// 
 373 
 374         /// 
 375 
 376         private static DirectoryEntry GetDirectoryObject(string domainReference)
 377         {
 378 
 379             DirectoryEntry entry = new DirectoryEntry(ADPath + domainReference, ADUser, ADPassword, AuthenticationTypes.Secure);
 380 
 381             return entry;
 382 
 383         }
 384 
 385 
 386 
 387         /// 
 388 
 389         /// 获得以UserName,Password创建的DirectoryEntry
 390 
 391         /// 
 392 
 393         /// 
 394 
 395         /// 
 396 
 397         /// 
 398 
 399         /// 
 400 
 401         private static DirectoryEntry GetDirectoryObject(string domainReference, string userName, string password)
 402         {
 403 
 404             DirectoryEntry entry = new DirectoryEntry(ADPath + domainReference, userName, password, AuthenticationTypes.Secure);
 405 
 406             return entry;
 407 
 408         }
 409 
 410 
 411 
 412         #endregion
 413 
 414 
 415 
 416         #region GetDirectoryEntry
 417 
 418 
 419 
 420         /// 
 421 
 422         /// 根据用户公共名称取得用户的 对象
 423 
 424         /// 
 425 
 426         /// 用户公共名称
 427 
 428         /// 如果找到该用户,则返回用户的 对象;否则返回 null
 429 
 430         public static DirectoryEntry GetDirectoryEntry(string commonName)
 431         {
 432 
 433             DirectoryEntry de = GetDirectoryObject();
 434 
 435             DirectorySearcher deSearch = new DirectorySearcher(de);
 436 
 437             deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName + "))";
 438 
 439             deSearch.SearchScope = SearchScope.Subtree;
 440 
 441 
 442 
 443             try
 444             {
 445 
 446                 SearchResult result = deSearch.FindOne();
 447 
 448                 de = new DirectoryEntry(result.Path);
 449 
 450                 return de;
 451 
 452             }
 453 
 454             catch
 455             {
 456 
 457                 return null;
 458 
 459             }
 460 
 461         }
 462 
 463 
 464 
 465         /// 
 466 
 467         /// 根据用户公共名称和密码取得用户的 对象。
 468 
 469         /// 
 470 
 471         /// 用户公共名称
 472 
 473         /// 用户密码
 474 
 475         /// 如果找到该用户,则返回用户的 对象;否则返回 null
 476 
 477         public static DirectoryEntry GetDirectoryEntry(string commonName, string password)
 478         {
 479 
 480             DirectoryEntry de = GetDirectoryObject(commonName, password);
 481 
 482             DirectorySearcher deSearch = new DirectorySearcher(de);
 483 
 484             deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName + "))";
 485 
 486             deSearch.SearchScope = SearchScope.Subtree;
 487 
 488 
 489 
 490             try
 491             {
 492 
 493                 SearchResult result = deSearch.FindOne();
 494 
 495                 de = new DirectoryEntry(result.Path);
 496 
 497                 return de;
 498 
 499             }
 500 
 501             catch
 502             {
 503 
 504                 return null;
 505 
 506             }
 507 
 508         }
 509 
 510 
 511 
 512         /// 
 513 
 514         /// 根据用户帐号称取得用户的 对象
 515 
 516         /// 
 517 
 518         /// 用户帐号名
 519 
 520         /// 如果找到该用户,则返回用户的 对象;否则返回 null
 521 
 522         public static DirectoryEntry GetDirectoryEntryByAccount(string sAMAccountName)
 523         {
 524 
 525             DirectoryEntry de = GetDirectoryObject();
 526 
 527             DirectorySearcher deSearch = new DirectorySearcher(de);
 528 
 529             deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(sAMAccountName=" + sAMAccountName + "))";
 530 
 531             deSearch.SearchScope = SearchScope.Subtree;
 532 
 533 
 534 
 535             try
 536             {
 537 
 538                 SearchResult result = deSearch.FindOne();
 539 
 540                 de = new DirectoryEntry(result.Path);
 541 
 542                 return de;
 543 
 544             }
 545 
 546             catch
 547             {
 548 
 549                 return null;
 550 
 551             }
 552 
 553         }
 554 
 555 
 556 
 557         /// 
 558 
 559         /// 根据用户帐号和密码取得用户的 对象
 560 
 561         /// 
 562 
 563         /// 用户帐号名
 564 
 565         /// 用户密码
 566 
 567         /// 如果找到该用户,则返回用户的 对象;否则返回 null
 568 
 569         public static DirectoryEntry GetDirectoryEntryByAccount(string sAMAccountName, string password)
 570         {
 571 
 572             DirectoryEntry de = GetDirectoryEntryByAccount(sAMAccountName);
 573 
 574             if (de != null)
 575             {
 576 
 577                 string commonName = de.Properties["cn"][0].ToString();
 578 
 579 
 580 
 581                 if (GetDirectoryEntry(commonName, password) != null)
 582 
 583                     return GetDirectoryEntry(commonName, password);
 584 
 585                 else
 586 
 587                     return null;
 588 
 589             }
 590 
 591             else
 592             {
 593 
 594                 return null;
 595 
 596             }
 597 
 598         }
 599 
 600 
 601 
 602         /// 
 603 
 604         /// 根据组名取得用户组的 对象
 605 
 606         /// 
 607 
 608         /// 组名
 609 
 610         /// 
 611 
 612         public static DirectoryEntry GetDirectoryEntryOfGroup(string groupName)
 613         {
 614 
 615             DirectoryEntry de = GetDirectoryObject();
 616 
 617             DirectorySearcher deSearch = new DirectorySearcher(de);
 618 
 619             deSearch.Filter = "(&(objectClass=group)(cn=" + groupName + "))";
 620 
 621             deSearch.SearchScope = SearchScope.Subtree;
 622 
 623 
 624 
 625             try
 626             {
 627 
 628                 SearchResult result = deSearch.FindOne();
 629 
 630                 de = new DirectoryEntry(result.Path);
 631 
 632                 return de;
 633 
 634             }
 635 
 636             catch
 637             {
 638 
 639                 return null;
 640 
 641             }
 642 
 643         }
 644 
 645 
 646 
 647         #endregion
 648 
 649 
 650 
 651         #region GetProperty
 652 
 653 
 654 
 655         /// 
 656 
 657         /// 获得指定 指定属性名对应的值
 658 
 659         /// 
 660 
 661         /// 
 662 
 663         /// 属性名称
 664 
 665         /// 属性值
 666 
 667         public static string GetProperty(DirectoryEntry de, string propertyName)
 668         {
 669 
 670             if (de.Properties.Contains(propertyName))
 671             {
 672 
 673                 return de.Properties[propertyName][0].ToString();
 674 
 675             }
 676 
 677             else
 678             {
 679 
 680                 return string.Empty;
 681 
 682             }
 683 
 684         }
 685 
 686 
 687 
 688         /// 
 689 
 690         /// 获得指定搜索结果 中指定属性名对应的值
 691 
 692         /// 
 693 
 694         /// 
 695 
 696         /// 属性名称
 697 
 698         /// 属性值
 699 
 700         public static string GetProperty(SearchResult searchResult, string propertyName)
 701         {
 702 
 703             if (searchResult.Properties.Contains(propertyName))
 704             {
 705 
 706                 return searchResult.Properties[propertyName][0].ToString();
 707 
 708             }
 709 
 710             else
 711             {
 712 
 713                 return string.Empty;
 714 
 715             }
 716 
 717         }
 718 
 719 
 720 
 721         #endregion
 722 
 723 
 724 
 725         /// 
 726 
 727         /// 设置指定 的属性值
 728 
 729         /// 
 730 
 731         /// 
 732 
 733         /// 属性名称
 734 
 735         /// 属性值
 736 
 737         public static void SetProperty(DirectoryEntry de, string propertyName, string propertyValue)
 738         {
 739 
 740             if (propertyValue != string.Empty || propertyValue != "" || propertyValue != null)
 741             {
 742 
 743                 if (de.Properties.Contains(propertyName))
 744                 {
 745 
 746                     de.Properties[propertyName][0] = propertyValue;
 747 
 748                 }
 749 
 750                 else
 751                 {
 752 
 753                     de.Properties[propertyName].Add(propertyValue);
 754 
 755                 }
 756 
 757             }
 758 
 759         }
 760 
 761 
 762 
 763         /// 
 764 
 765         /// 创建新的用户
 766 
 767         /// 
 768 
 769         /// DN 位置。例如:OU=共享平台 或 CN=Users
 770 
 771         /// 公共名称
 772 
 773         /// 帐号
 774 
 775         /// 密码
 776 
 777         /// 
 778 
 779         public static DirectoryEntry CreateNewUser(string ldapDN, string commonName, string sAMAccountName, string password)
 780         {
 781 
 782             DirectoryEntry entry = GetDirectoryObject();
 783 
 784             DirectoryEntry subEntry = entry.Children.Find(ldapDN);
 785 
 786             DirectoryEntry deUser = subEntry.Children.Add("CN=" + commonName, "user");
 787 
 788             deUser.Properties["sAMAccountName"].Value = sAMAccountName;
 789 
 790             deUser.CommitChanges();
 791             deUser.AuthenticationType = AuthenticationTypes.Secure;
 792             object[] PSD = new object[] { SetSecurePassword() };
 793             object ret = deUser.Invoke("SetPassword", PSD);
 794             //  ADHelper.SetPassword(commonName, password);
 795             ADHelper.EnableUser(commonName);
 796 
 797 
 798             deUser.Close();
 799 
 800             return deUser;
 801 
 802         }
 803 
 804         public static string SetSecurePassword()
 805         {
 806             //RandomPassword rp = new RandomPassword();
 807             return "qwe12d.";
 808         }
 809 
 810 
 811         public void SetPassword(DirectoryEntry newuser)
 812         {
 813 
 814 
 815             newuser.AuthenticationType = AuthenticationTypes.Secure;
 816             object[] password = new object[] { SetSecurePassword() };
 817             object ret = newuser.Invoke("SetPassword", password);
 818             newuser.CommitChanges();
 819             newuser.Close();
 820 
 821         }
 822 
 823         public static bool IsRepeat(string commonName)
 824         {
 825             PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, DomainName, "Administrator", "123456");
 826             UserPrincipal userPrincipal = UserPrincipal.FindByIdentity
 827                     (principalContext, commonName);
 828             if (userPrincipal==null)
 829             {
 830                 return false;
 831             }
 832             try
 833             {
 834                 return (bool)userPrincipal.Enabled;
 835             }
 836             finally {
 837                 if (userPrincipal!=null)
 838                 {
 839 
 840                     userPrincipal.Dispose();
 841                 }
 842                 if (principalContext!=null)
 843                 {
 844 
 845                     principalContext.Dispose();
 846                 }
 847             }
 848           
 849 
 850           //  userPrincipal.Save();
 851         }
 852         /// 
 853 
 854         /// 创建新的用户。默认创建在 Users 单元下。
 855 
 856         /// 
 857 
 858         /// 公共名称
 859 
 860         /// 帐号
 861 
 862         /// 密码
 863 
 864         /// 
 865 
 866         public static DirectoryEntry CreateNewUser(string commonName, string sAMAccountName, string password)
 867         {
 868 
 869             return CreateNewUser("CN=Users", commonName, sAMAccountName, password);
 870 
 871         }
 872 
 873 
 874 
 875         /// 
 876 
 877         /// 判断指定公共名称的用户是否存在
 878 
 879         /// 
 880 
 881         /// 用户公共名称
 882 
 883         /// 如果存在,返回 true;否则返回 false
 884 
 885         public static bool IsUserExists(string commonName)
 886         {
 887 
 888             DirectoryEntry de = GetDirectoryObject();
 889 
 890             DirectorySearcher deSearch = new DirectorySearcher(de);
 891 
 892             deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName + "))";       // LDAP 查询串
 893 
 894             SearchResultCollection results = deSearch.FindAll();
 895 
 896 
 897 
 898             if (results.Count == 0)
 899 
 900                 return false;
 901 
 902             else
 903 
 904                 return true;
 905 
 906         }
 907 
 908 
 909 
 910         /// 
 911 
 912         /// 判断用户帐号是否激活
 913 
 914         /// 
 915 
 916         /// 用户帐号属性控制器
 917 
 918         /// 如果用户帐号已经激活,返回 true;否则返回 false
 919 
 920         public static bool IsAccountActive(int userAccountControl)
 921         {
 922 
 923             int userAccountControl_Disabled = Convert.ToInt32(ADS_USER_FLAG_ENUM.ADS_UF_ACCOUNTDISABLE);
 924 
 925             int flagExists = userAccountControl & userAccountControl_Disabled;
 926 
 927 
 928 
 929             if (flagExists > 0)
 930 
 931                 return false;
 932 
 933             else
 934 
 935                 return true;
 936 
 937         }
 938 
 939 
 940 
 941         /// 
 942 
 943         /// 判断用户与密码是否足够以满足身份验证进而登录
 944 
 945         /// 
 946 
 947         /// 用户公共名称
 948 
 949         /// 密码
 950 
 951         /// 如能可正常登录,则返回 true;否则返回 false
 952 
 953         public static LoginResult Login(string commonName, string password)
 954         {
 955 
 956             DirectoryEntry de = GetDirectoryEntry(commonName,password);
 957 
 958 
 959 
 960             if (de != null)
 961             {
 962 
 963                 // 必须在判断用户密码正确前,对帐号激活属性进行判断;否则将出现异常。
 964 
 965                 int userAccountControl = Convert.ToInt32(de.Properties["userAccountControl"][0]);
 966 
 967                 de.Close();
 968 
 969 
 970 
 971                 if (!IsAccountActive(userAccountControl))
 972 
 973                     return LoginResult.LOGIN_USER_ACCOUNT_INACTIVE;
 974 
 975 
 976 
 977                 if (GetDirectoryEntry(commonName, password) != null)
 978 
 979                     return LoginResult.LOGIN_USER_OK;
 980 
 981                 else
 982 
 983                     return LoginResult.LOGIN_USER_PASSWORD_INCORRECT;
 984 
 985             }
 986 
 987             else
 988             {
 989 
 990                 return LoginResult.LOGIN_USER_DOESNT_EXIST;
 991 
 992             }
 993 
 994         }
 995 
 996 
 997 
 998         /// 
 999 
1000         /// 判断用户帐号与密码是否足够以满足身份验证进而登录
1001 
1002         /// 
1003 
1004         /// 用户帐号
1005 
1006         /// 密码
1007 
1008         /// 如能可正常登录,则返回 true;否则返回 false
1009 
1010         public static LoginResult LoginByAccount(string sAMAccountName, string password)
1011         {
1012 
1013             DirectoryEntry de = GetDirectoryEntryByAccount(sAMAccountName);
1014 
1015 
1016 
1017             if (de != null)
1018             {
1019 
1020                 // 必须在判断用户密码正确前,对帐号激活属性进行判断;否则将出现异常。
1021 
1022                 int userAccountControl = Convert.ToInt32(de.Properties["userAccountControl"][0]);
1023 
1024                 de.Close();
1025 
1026 
1027 
1028                 if (!IsAccountActive(userAccountControl))
1029 
1030                     return LoginResult.LOGIN_USER_ACCOUNT_INACTIVE;
1031 
1032 
1033 
1034                 if (GetDirectoryEntryByAccount(sAMAccountName, password) != null)
1035 
1036                     return LoginResult.LOGIN_USER_OK;
1037 
1038                 else
1039 
1040                     return LoginResult.LOGIN_USER_PASSWORD_INCORRECT;
1041 
1042             }
1043 
1044             else
1045             {
1046 
1047                 return LoginResult.LOGIN_USER_DOESNT_EXIST;
1048 
1049             }
1050 
1051         }
1052 
1053 
1054 
1055         /// 
1056 
1057         /// 设置用户密码,管理员可以通过它来修改指定用户的密码。
1058 
1059         /// 
1060 
1061         /// 用户公共名称
1062 
1063         /// 用户新密码
1064 
1065         public static void SetPassword(string commonName, string newPassword)
1066         {
1067 
1068             DirectoryEntry de = GetDirectoryObject(commonName);
1069 
1070 
1071 
1072             // 模拟超级管理员,以达到有权限修改用户密码
1073 
1074             impersonate.BeginImpersonate();
1075 
1076             de.Invoke("SetPassword", new object[] { newPassword });
1077 
1078             impersonate.StopImpersonate();
1079 
1080 
1081 
1082             de.Close();
1083 
1084 
1085             //de.AuthenticationType = AuthenticationTypes.Secure;
1086             //object[] password = new object[] { newPassword };
1087             //object ret = de.Invoke("SetPassword", password);
1088             //de.CommitChanges();
1089             //de.Close();
1090 
1091         }
1092 
1093 
1094 
1095         private static DirectoryEntry GetUser(string UserName, string oldpsw)
1096         {
1097 
1098             DirectoryEntry de = GetDirectoryObject();
1099             DirectorySearcher deSearch = new DirectorySearcher();
1100             deSearch.SearchRoot = de;
1101 
1102             deSearch.Filter = "(&(objectClass=user)(SAMAccountName=" + UserName + "))";
1103             deSearch.SearchScope = SearchScope.Subtree;
1104             SearchResult results = deSearch.FindOne();
1105 
1106             if (!(results == null))
1107             {
1108                 // **THIS IS THE MOST IMPORTANT LINE**
1109                 de = new DirectoryEntry(results.Path, "username", "password", AuthenticationTypes.Secure);
1110                 return de;
1111             }
1112             else
1113             {
1114                 return null;
1115             }
1116         }
1117 
1118 
1119 
1120         public static bool ChangePassword(string UserName, string strOldPassword, string strNewPassword)
1121         {
1122 
1123             bool passwordChanged = false;
1124 
1125             DirectoryEntry oDE = GetUser(UserName, strOldPassword);
1126 
1127             if (oDE != null)
1128             {
1129 
1130                 // Change the password.
1131                 oDE.Invoke("ChangePassword", new object[] { strOldPassword, strNewPassword });
1132                 passwordChanged = true;
1133 
1134             }
1135             return passwordChanged;
1136         }
1137 
1138 
1139 
1140         /// 
1141 
1142         /// 设置帐号密码,管理员可以通过它来修改指定帐号的密码。
1143 
1144         /// 
1145 
1146         /// 用户帐号
1147 
1148         /// 用户新密码
1149 
1150         public static void SetPasswordByAccount(string sAMAccountName, string newPassword)
1151         {
1152 
1153             DirectoryEntry de = GetDirectoryEntryByAccount(sAMAccountName);
1154 
1155 
1156 
1157             // 模拟超级管理员,以达到有权限修改用户密码
1158 
1159             IdentityImpersonation impersonate = new IdentityImpersonation(ADUser, ADPassword, DomainName);
1160 
1161             impersonate.BeginImpersonate();
1162 
1163             de.Invoke("SetPassword", new object[] { newPassword });
1164 
1165             impersonate.StopImpersonate();
1166 
1167 
1168 
1169             de.Close();
1170 
1171         }
1172 
1173 
1174 
1175         /// 
1176 
1177         /// 修改用户密码
1178 
1179         /// 
1180 
1181         /// 用户公共名称
1182 
1183         /// 旧密码
1184 
1185         /// 新密码
1186 
1187         public static void ChangeUserPassword(string commonName, string oldPassword, string newPassword)
1188         {
1189 
1190             // to-do: 需要解决密码策略问题
1191 
1192             DirectoryEntry oUser = GetDirectoryEntry(commonName);
1193 
1194             oUser.Invoke("ChangePassword", new Object[] { oldPassword, newPassword });
1195 
1196             oUser.Close();
1197 
1198         }
1199 
1200 
1201 
1202         /// 
1203 
1204         /// 启用指定公共名称的用户
1205 
1206         /// 
1207 
1208         /// 用户公共名称
1209 
1210         public static void EnableUser(string commonName)
1211         {
1212 
1213             try
1214             {
1215                 //DomainName:填写域名, Administrator表示登录账户,123456密码。
1216                 PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, DomainName, "Administrator", "123456");
1217                 UserPrincipal userPrincipal = UserPrincipal.FindByIdentity
1218                         (principalContext,commonName);
1219 
1220                 userPrincipal.Enabled = true;
1221                 //如果是禁用这里就改成false
1222                 userPrincipal.Save();
1223 
1224             }
1225             catch (Exception ex)
1226             {
1227                 Console.WriteLine(ex.Message);
1228             }
1229         }
1230 
1231 
1232 
1233         /// 
1234 
1235         /// 启用指定 的用户
1236 
1237         /// 
1238 
1239         /// 
1240 
1241         public static void EnableUser(DirectoryEntry de)
1242         {
1243             try
1244             {
1245                 impersonate.BeginImpersonate();
1246                 de.Properties["userAccountControl"].Value = ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_NORMAL_ACCOUNT | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_TRUSTED_FOR_DELEGATION | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD;
1247                 de.CommitChanges();
1248 
1249                 impersonate.StopImpersonate();
1250 
1251                 de.Close();
1252 
1253             }
1254             catch (Exception ex)
1255             {
1256                 throw;
1257             }
1258 
1259         }
1260 
1261 
1262 
1263         /// 
1264 
1265         /// 禁用指定公共名称的用户
1266 
1267         /// 
1268 
1269         /// 用户公共名称
1270 
1271         public static void DisableUser(string commonName)
1272         {
1273 
1274             //DisableUser(GetDirectoryEntry(commonName));
1275             try
1276             {
1277                 //  PrincipalContext principalContext = new PrincipalContext(ContextType.Domain);
1278                 PrincipalContext principalContext = new PrincipalContext(ContextType.Domain, DomainName, "Administrator", "123456");
1279                 UserPrincipal userPrincipal = UserPrincipal.FindByIdentity
1280                         (principalContext, commonName);
1281 
1282                 userPrincipal.Enabled = false;
1283 
1284                 userPrincipal.Save();
1285 
1286             }
1287             catch (Exception ex)
1288             {
1289                 Console.WriteLine(ex.Message);
1290             }
1291         }
1292 
1293 
1294 
1295         /// 
1296 
1297         /// 禁用指定 的用户
1298 
1299         /// 
1300 
1301         /// 
1302 
1303         public static void DisableUser(DirectoryEntry de)
1304         {
1305 
1306             impersonate.BeginImpersonate();
1307 
1308             de.Properties["userAccountControl"][0] = ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_NORMAL_ACCOUNT | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_DONT_EXPIRE_PASSWD | ADHelper.ADS_USER_FLAG_ENUM.ADS_UF_ACCOUNTDISABLE;
1309 
1310             de.CommitChanges();
1311 
1312             impersonate.StopImpersonate();
1313 
1314             de.Close();
1315 
1316         }
1317 
1318 
1319 
1320         /// 
1321 
1322         /// 将指定的用户添加到指定的组中。默认为 Users 下的组和用户。
1323 
1324         /// 
1325 
1326         /// 用户公共名称
1327 
1328         /// 组名
1329 
1330         public static void AddUserToGroup(string userCommonName, string groupName)
1331         {
1332 
1333             DirectoryEntry oGroup = GetDirectoryEntryOfGroup(groupName);
1334 
1335             DirectoryEntry oUser = GetDirectoryEntry(userCommonName);
1336 
1337 
1338 
1339             impersonate.BeginImpersonate();
1340 
1341             oGroup.Properties["member"].Add(oUser.Properties["distinguishedName"].Value);
1342 
1343             oGroup.CommitChanges();
1344 
1345             impersonate.StopImpersonate();
1346 
1347 
1348 
1349             oGroup.Close();
1350 
1351             oUser.Close();
1352 
1353         }
1354 
1355 
1356 
1357         /// 
1358 
1359         /// 将用户从指定组中移除。默认为 Users 下的组和用户。
1360 
1361         /// 
1362 
1363         /// 用户公共名称
1364 
1365         /// 组名
1366 
1367         public static void RemoveUserFromGroup(string userCommonName, string groupName)
1368         {
1369 
1370             DirectoryEntry oGroup = GetDirectoryEntryOfGroup(groupName);
1371 
1372             DirectoryEntry oUser = GetDirectoryEntry(userCommonName);
1373 
1374 
1375 
1376             impersonate.BeginImpersonate();
1377 
1378             oGroup.Properties["member"].Remove(oUser.Properties["distinguishedName"].Value);
1379 
1380             oGroup.CommitChanges();
1381 
1382             impersonate.StopImpersonate();
1383 
1384 
1385 
1386             oGroup.Close();
1387 
1388             oUser.Close();
1389 
1390         }
1391 
1392 
1393 
1394     }
1395 
1396 
1397 
1398     /// 
1399 
1400     /// 用户模拟角色类。实现在程序段内进行用户角色模拟。
1401 
1402     /// 
1403 
1404     public class IdentityImpersonation
1405     {
1406 
1407         [DllImport("advapi32.dll", SetLastError = true)]
1408 
1409         public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
1410 
1411 
1412 
1413         [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
1414 
1415         public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);
1416 
1417 
1418 
1419         [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
1420 
1421         public extern static bool CloseHandle(IntPtr handle);
1422 
1423 
1424 
1425         // 要模拟的用户的用户名、密码、域(机器名)
1426 
1427         private String _sImperUsername;
1428 
1429         private String _sImperPassword;
1430 
1431         private String _sImperDomain;
1432 
1433         // 记录模拟上下文
1434 
1435         private WindowsImpersonationContext _imperContext;
1436 
1437         private IntPtr _adminToken;
1438 
1439         private IntPtr _dupeToken;
1440 
1441         // 是否已停止模拟
1442 
1443         private Boolean _bClosed;
1444 
1445 
1446 
1447         /// 
1448 
1449         /// 构造函数
1450 
1451         /// 
1452 
1453         /// 所要模拟的用户的用户名
1454 
1455         /// 所要模拟的用户的密码
1456 
1457         /// 所要模拟的用户所在的域
1458 
1459         public IdentityImpersonation(String impersonationUsername, String impersonationPassword, String impersonationDomain)
1460         {
1461 
1462             _sImperUsername = impersonationUsername;
1463 
1464             _sImperPassword = impersonationPassword;
1465 
1466             _sImperDomain = impersonationDomain;
1467 
1468 
1469 
1470             _adminToken = IntPtr.Zero;
1471 
1472             _dupeToken = IntPtr.Zero;
1473 
1474             _bClosed = true;
1475 
1476         }
1477 
1478 
1479 
1480         /// 
1481 
1482         /// 析构函数
1483 
1484         /// 
1485 
1486         ~IdentityImpersonation()
1487         {
1488 
1489             if (!_bClosed)
1490             {
1491 
1492                 StopImpersonate();
1493 
1494             }
1495 
1496         }
1497 
1498 
1499 
1500         /// 
1501 
1502         /// 开始身份角色模拟。
1503 
1504         /// 
1505 
1506         /// 
1507 
1508         public Boolean BeginImpersonate()
1509         {
1510 
1511             Boolean bLogined = LogonUser(_sImperUsername, _sImperDomain, _sImperPassword, 2, 0, ref _adminToken);
1512 
1513 
1514 
1515             if (!bLogined)
1516             {
1517 
1518                 return false;
1519 
1520             }
1521 
1522 
1523 
1524             Boolean bDuped = DuplicateToken(_adminToken, 2, ref _dupeToken);
1525 
1526 
1527 
1528             if (!bDuped)
1529             {
1530 
1531                 return false;
1532 
1533             }
1534 
1535 
1536 
1537             WindowsIdentity fakeId = new WindowsIdentity(_dupeToken);
1538 
1539             _imperContext = fakeId.Impersonate();
1540 
1541 
1542 
1543             _bClosed = false;
1544 
1545 
1546 
1547             return true;
1548 
1549         }
1550 
1551 
1552         /// 
1553 
1554         /// 停止身分角色模拟。
1555 
1556         /// 
1557 
1558         public void StopImpersonate()
1559         {
1560 
1561             _imperContext.Undo();
1562 
1563             CloseHandle(_dupeToken);
1564 
1565             CloseHandle(_adminToken);
1566 
1567             _bClosed = true;
1568 
1569         }
1570 
1571     }
1572 }
ADHelper.cs

该文章在 2021/6/27 0:00:01 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved