前言
光copy幾段代碼的文章沒什么意思,本章上最基礎的代碼,主要是為了從編程方面聊LDAP和DN,其它的后面聊,一步步慢慢來吧。
Active Directory編程須知
1.域控服務器:
Windows Server 2000及以上;推薦Windows Server為2003以上(因為Microsoft在2000以后的Server中對AD有了新的架構級的修改,2000版本的系統與之后的操作系統AD架構方面存在差異)。個人使用的是Windows Server 2012 R2版本做測試 。
2.服務器角色:
已經完成安裝Active Directory域控角色,並且已經成功部署。
3.開發工具
Visual Studio 2008及以上。
4.NET Framework版本
.NET Framework2.0及以上.NET Framework4.6.2以下(本文編寫時建議請先使用4.6.2以下的程序集,以后這里會做修改。)
5.核心程序集
System.DirectoryServices.dll;
System.DirectoryServices 命名空間中提供輕松訪問到 Active Directory 域服務,從托管代碼。 該命名空間包含兩個常用組件,DirectoryEntry和DirectorySearcher。
詳細資料:https://msdn.microsoft.com/zh-cn/library/system.directoryservices
System.DirectoryServices.AccountManagement.dll;
System.DirectoryServices.AccountManagement 命名空間在多個主體存儲提供統一訪問和操作的用戶、 計算機和組的安全主體︰ Active Directory 域服務 (AD DS)、 Active Directory 輕型目錄服務 (AD LDS) 和 Machine SAM (MSAM)。
詳細資料:https://msdn.microsoft.com/zh-cn/library/System.DirectoryServices.AccountManagement
System.DirectoryServices.Protocols.dll;
System.DirectoryServices.Protocols 命名空間提供了標准輕型目錄訪問協議 (LDAP) 版本 3 (V3) 和目錄服務標記語言 (DSML) 版本 2.0 (V2) 中定義的方法。
詳細資料:https://msdn.microsoft.com/zh-cn/library/System.DirectoryServices.Protocols
測試連接域控服務器(AD DS)
在我們討論LDAP之前,先看下面這段代碼:
1 using System.DirectoryServices; 2 namespace ADTest 3 { 4 class Program 5 { 6 static void Main(string[] args) 7 { 8 DirectoryEntry Entry = IsConnected(ADServerIp, ADUser, ADPasssWord); 9 Console.Write(Entry.SchemaClassName); 10 Console.ReadKey(); 11 } 12 /// <summary> 13 /// 域控服務器IP或域名 14 /// </summary> 15 private static string ADServerIp = "192.168.241.3"; 16 /// <summary> 17 /// AD管理員帳號 18 /// </summary> 19 private static string ADUser = @"Domain"; 20 /// <summary> 21 /// AD管理員密碼 22 /// </summary> 23 private static string ADPasssWord = "p@ssw0rd"; 24 /// <summary> 25 /// 測試連接域控服務器 26 /// </summary> 27 /// <param name="domainIP">域控服務器IP或域名</param> 28 /// <param name="userName">賬號</param> 29 /// <param name="userPwd">密碼</param> 30 /// <returns></returns> 31 public static DirectoryEntry IsConnected(string domainIP, string userName, string userPwd) 32 { 33 DirectoryEntry entry = null; 34 try 35 { 36 entry = new DirectoryEntry("LDAP://" + domainIP, userName, userPwd); 37 return entry; 38 } 39 catch (Exception ex) 40 { 41 throw ex; 42 } 43 } 44 } 45 }
斷點調試,我們看看加載的DirectoryEntry對象的屬性:
這里主要說說這個非常關鍵的Path。從圖片對比,DirectoryEntry的構造函數傳入的Path參數與程序得到的DirectoryEntry的Path屬性的值相等。我們看下官網對這個Path的定義。
我個人的簡單理解是:這里的path是一種需要符合LDAP協議的連接域控服務器的連接字符串。那LDAP協議到底是什么?
LDAP協議詳解
LDAP協議,中文名:輕量級目錄訪問協議(Lightweight Directory Access Protocol),是為了實現目錄服務的信息訪問而構建的一種協議,構建與目錄服務的協議上運行於TCP/IP協議棧上面的一層。
用於連接域服務器的特定字符串格式,可以理解為MSSQL的連接字符串用於加載不同服務器中的不同的數據庫,而LADP協議的服務器連接串,是加載不同服務器的,域對象、用戶對象、組織單位對象等等。
LADP協議由核心三部分組成:LDAP://DomainIP/DN
DomainIP:是我們要連接的域控服務器的IP或域名
DN :全稱叫完全限定名(Distinguished Name),用於標識對象在活動目錄中完整路徑。RDN用來標識容器中的一個對象,是DN中最前面的一項(第一個逗號前).例如:
那我們需要驗證一下,使用如下代碼得到的運行結果:
1 static void Main(string[] args) 2 { 3 DirectoryEntry Entry = new DirectoryEntry(@"LDAP://192.168.241.3/CN=李四,OU=人事部,OU=徐匯區事業部,OU=上海分公司,DC=IFire47,DC=com", "Domain", "p@ssw0rd"); 4 Console.Write(Entry.SchemaClassName); 5 Console.ReadKey(); 6 }
驗證通過。但是DN內具體的到底是怎么回事呢?坑還是要一步步填。
DN(Distinguished Name)詳細分析
詳細聊DN之前我們先要了解DN的數據結構:
將圖中的域對象distinguishedName屬性按層次排列如下(不清,請右鍵查看原圖URL):
我們可以看到DN的數據規律為:從左向右(RDN+嵌套在最里層的OU向外到第一級別OU+Domain)。因為AD的數據是嵌套一級一級的存儲,形成樹狀型管理結構,而DN的信息是也是按照樹型結構組織的。所以在一個完整的LDAP協議中,我們可以根據DN從右至左推算出最終加載出來的對象的類型,及對象所在的具體位置(所以能明白DN是唯一的)。
總結出如下規律:
DN:Distinguished Name(完全限定名),主要包含如下三種: | |
DC | (Domain Component) |
CN | (Common Name) |
OU | (Organizational Unit) |
LDAP 命名規則及其 Active Directory 對應屬性規則 |
|
DN | Active Directory |
cn=公用名 |
cn=公用名 |
ou=部門 |
ou=部門 |
dc=DNS域名 |
dc=域組件 |
DN中各命名的用法 | |
cn:主要用於 user 對象類,但它是通用名稱,除了OU,DC需要特殊標識,其他容器全部使用CN作為標識。 |
|
ou:主要用於 organizational unit (OU) 對象類,只要組織單位是管理員手動創建,非系統默認容器,就需要使用OU做標識。 |
|
dc :主要用於 domainDns 對象類,表示DNS域名。 |
|
示例: |
|
OU=徐匯區事業部,OU=上海分公司,DC=IFire47,DC=com | |
解讀:域(IFire47.com)里的(ou)上海分公司里的(ou)(徐匯區事業部) | |
CN=張三,OU=銷售部,OU=北京昌平區事業部,OU=北京分公司,DC=IFire47,DC=com | |
解讀:域(IFire47.com)里的(ou)北京分公司里的(ou)北京昌平區事業部里的(ou)銷售部的(user)張三 |
結語
以上是本文的全部內容,主要從程序方面認識LDAP協議的用處,且掌握AD中域對象的distinguishedName屬性的數據意義為后面的編程做鋪墊。
本文章最后修改時間:2017年4月16日02:36:37
作者:IFire47 出處:http://www.cnblogs.com/IFire47/