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

前段时间(因为懒得找具体的时间了)公司说让系统可以进行对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;
            }

        }

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

原文地址:https://www.cnblogs.com/mosdong/p/10489161.html

时间: 2024-10-15 12:44:30

C# 关于AD域的操作 (首博)的相关文章

AD 域服务简介(三)- Java 对 AD 域用户的增删改查操作

博客地址:http://www.moonxy.com 关于AD 域服务器搭建及其使用,请参阅:AD 域服务简介(一) - 基于 LDAP 的 AD 域服务器搭建及其使用 Java 获取 AD 域用户,请参阅:AD 域服务简介(二)- Java 获取 AD 域用户 一.前言 在日常的开发中,为了实现单点登录,需要对域用户进行增删改查操作,以维持最新的用户信息,确保系统的安全. 二.Java 对 AD 域用户的增删改查操作 package com.moonxy.ad; import java.uti

.net操作AD域

using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Configuration;using System.DirectoryServices;namespace OperateADLibrary{    public class OperateAD    {        /// <summary>        /// 域名        /// <

JAVA使用Ldap操作AD域

项目上遇到的需要在集成 操作域用户的信息的功能,第一次接触ad域,因为不了解而且网上其他介绍不明确,比较费时,这里记录下. 说明: (1). 特别注意:Java操作查询域用户信息获取到的数据和域管理员在电脑上操作查询的数据可能会存在差异(同一个意思的表示字段,两者可能不同). (2). 连接ad域有两个地址: ldap://XXXXX.com:389 和 ldap://XXXXX.com:636(SSL). (3). 端口389用于一般的连接,例如登录,查询等非密码操作,端口636安全性较高,用

Windows Server 2012 AD域管理创建

前言 关于AD域管理及其权限划分概论: 1. AD域源于微软,适用于windows,为企业集中化管理和信息安全提供强力保障. 2. 提供域中文件夹共享,但同时又对不同用户有不用的权限. 3.通过对设备限制USB接口,网络访问特定网站来实现对企业内部信息的保护和防止流失. 4.个人文件夹可以重定向到服务器文件夹上,实现真正的在同一个域中使用者数据不受固定PC限制既数据跟随用走. 5.用户的权限不需要定制,只需要加入若干个带有不同权限属性的固定组就可以获得相应的权限功能. 我们按照下图来创建第一个林

AD域控制器所有使用的端口明细列表

AD域控制器所有使用的端口明细列表 :lol 端口 协议 应用程序协议 系统服务名称 n/a GRE GRE(IP 协议 47) 路由和远程访问 n/a ESP IPSec ESP(IP 协议 50) 路由和远程访问 n/a AH IPSec AH(IP 协议 51) 路由和远程访问 7 TCP Echo 简单 TCP/IP 服务 7 UDP Echo 简单 TCP/IP 服务 9 TCP Discard 简单 TCP/IP 服务 9 UDP Discard 简单 TCP/IP 服务 13 TC

Windows AD域升级方法

前面的博客中我谈到了网络的基本概念和网络参考模型,今天我们来谈企业中常用的技术,Windows AD 域,今天我的笔记将重点讲解Windows AD 域的升级和迁移方法,通过3个小实验进行配置,真实环境可能和虚拟机上的有些差异,请注意.(部分内容参考博友王哥哥哥哥和51CTO论坛上的一些资料,进行配置验证)如有错误,请各位博友批评指正. 实验一:Windows server 2003AD 升级到Windows servers2008AD 环境:1台Windows server 2003 域控,域

白话windows server 2012 r2和windows 7创建ad域与配置(安全版)

文章的可读性非常重要,这里提供的是一键式操作指南,即使之前完全没有接触,也可以配置完成. ad域的创建是为了便于公司的集中化管理,提高公司运作效率和安全性. 我的操作环境,本机是kali linux,虚拟机virtualbox分别安装一个windows7和windows server 2012 r2. 现在iso镜像类网站很多,建议采用msdn,相对可靠,内容全面. 在虚拟机上安装windows7(用户名为pjzhang)和windows server 2012 r2,都是相对简单的,百度会出现

C#获取AD域中计算机和用户的信息

如果你的计算机加入了某个AD域,则可以获取该域中所有的计算机和用户的信息. 所用程序集,需要.Net Framework 4. 添加程序集引用 System.DirectoryServices.AccountManagement 获取AD域名称,未加入AD域的,只能获取计算机名称. 如果未加入任何域,则后续的获取域用户.计算机等操作将无法进行,实例化域上下文对象时,会抛出异常. 1 IPGlobalProperties ipGlobalProperties = IPGlobalPropertie

jquery 文本域光标操作(选、添、删、取)

一.JQuery扩展 ; (function ($) { /* * 文本域光标操作(选.添.删.取)的jQuery扩展 http://www.cnblogs.com/phpyangbo/p/5528648.html */ $.fn.extend({ /* * 获取光标所在位置 */ iGetFieldPos: function () { var field = this.get(0); if (document.selection) { //IE $(this).focus(); var sel