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

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

问题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;}}

View Code

这个方法在本机的时候运行可以,但是到了客户测试那边还是报以上的错误,而且这个错误百度找不到,只好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);}}

View Code

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

问题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

转载于:https://www.cnblogs.com/mosdong/p/10489161.html

C# 关于AD域的操作 (首博)相关推荐

  1. windows server2012 AD域相关操作

    AD域主要作用就是集中管理,限制域内用户或计算机的所有操作,主要管理公司员工,就像通讯录一样,还能管理了电脑,打印机等, 权限管理,ADhelper 可以实现WEB方式的AD域管理,方便.快捷.其余不 ...

  2. AD域生产代码使用说明

    AD域生产代码使用说明 1. 每次需要检查的常量 2. 去隐私后的代码 3. 如何使用&测试案例 1. 每次需要检查的常量 CUSTOM_SAMA = '待填写内容' HAND的员工填HAND ...

  3. java操作ad域 免证书

    为什么80%的码农都做不了架构师?>>>    只提供免证书的认证部分,操作部分可以百度. 认证部分,得到context即可对域进行各种操作: /*** 本文章是针对java JND ...

  4. ad域控查看ldap端口命令_工作笔记(一)LDAP和AD介绍以及使用LDAP操作AD域

    1. LDAP入门 1.1 定义 LDAP是轻量目录访问协议(LightweightDirectory Access Protocol)的缩写,LDAP标准实际上是在X.500标准基础上产生的一个简化 ...

  5. java 操作AD域代码(跳过证书版)

    1.AD域操作类 @Slf4j public class ADOperator {private final DomainConfigModel adConfig;private static fin ...

  6. Java AD域登录实现正常本地登录操作

    Java 域登录 实现 前言 新建一个测试类 AD域的userName和passWord身份验证成功之后返回 身份验证失败之后返回 验证成功后将之代入项目登录的位置,根据自己的登录接口和登陆逻辑来修改 ...

  7. Ad域控之Ldaps以及Python操作

    背景 Python调用域控用来拿取用户信息. Windows10 添加ad域操作的功能 设置-->应用和功能-->可选功能--->Active Directory 用户和计算机 参考 ...

  8. powershell自动化操作AD域、Exchange邮箱系列(1)——powershell 简介

    从今天开始,系统的整理一下使用powershell自动化管理AD域账号.exchange邮箱账号的流程,最终我们将实现一个通过Web端调用powershell脚本实现的域控 邮箱管理系统. 目录 一. ...

  9. AD域账号日常维护常用操作

    查询指定OU中30天内未登录的AD帐号并导出记录 Get-ADuser -searchbase ' OU=MIS,DC=NDH,DC=com ' -filter * -Properties * | S ...

最新文章

  1. cp: /usr/bin/chromedriver: Operation not permitted
  2. CSDN 插件限时内测,新用户抢永久免费去广告特权!
  3. Atitit..css的体系结构
  4. spring beans源码解读之--Bean的注解(annotation)
  5. SAP Cloud SDK‘s Virtual Data Model
  6. 【OS学习笔记】二十七 保护模式八:任务切换的方法之----jmp与call的区别以及任务的中断嵌套
  7. 画米老鼠_蔡康永都在买的画你也买得起,村上隆作品收藏大全
  8. 请问,怎么在DBGRID中改变CELL内容
  9. SQL从入门到入魔之select简单查询
  10. 企业级docker私有仓库的配置与使用
  11. 对于Vue组件的初步认识(未整理)
  12. duplicate复制数据库
  13. JavaWeb的目录结构(1)
  14. 疫情之下, 远程办公软件是如何逆势增长的?
  15. ssm——整合,前端页面设计,分页
  16. linux查进程ps和top,linux进程查看top与ps
  17. 【风马一族_php】常用的语句
  18. [JS] 聊一聊File对象
  19. 考研英语词汇(部分)快速记忆
  20. 云计算技术体系结构由这四点组成

热门文章

  1. 新入手的iPhone 11不会玩?手势和按键操作大全,快捷玩机很简单
  2. Flutter开发之Http网络请求
  3. 【华为云技术分享】风格迁移——让你的照片秒变手绘日漫风,祝大家六一快乐!
  4. HTML做表格以及注册界面
  5. 中国轿车品牌如何突围之思 考
  6. ubuntu 16.04极速安装ROS-Kinetic,以及常见错误处理
  7. Python日记——柿子要捡软的捏,记第一只小爬虫
  8. 为什么要学习Java?|猿代码科技
  9. Flink SQL JSON Format 源码解析
  10. 技术面试中,什么样的问题才是好问题?