1. LDAP簡介
LDAP(輕量級目錄訪問協議,Lightweight Directory Access Protocol)是實現提供被稱為目錄服務的信息服務。目錄服務是一種特殊的數據庫系統,其專門針對讀取,瀏覽和搜索操作進行了特定的優化。目錄一般用來包含描述性的,基於屬性的信息並支持精細復雜的過濾能力。目錄一般不支持通用數據庫針對大量更新操作操作需要的復雜的事務管理或回卷策略。而目錄服務的更新則一般都非常簡單。這種目錄可以存儲包括個人信息、web鏈結、jpeg圖像等各種信息。為了訪問存儲在目錄中的信息,就需要使用運行在TCP/IP 之上的訪問協議—LDAP。
LDAP目錄中的信息是是按照樹型結構組織,具體信息存儲在條目(entry)的數據結構中。條目相當於關系數據庫中表的記錄;條目是具有區別名DN (Distinguished Name)的屬性(Attribute),DN是用來引用條目的,DN相當於關系數據庫表中的關鍵字(Primary Key)。屬性由類型(Type)和一個或多個值(Values)組成,相當於關系數據庫中的字段(Field)由字段名和數據類型組成,只是為了方便檢索的需要,LDAP中的Type可以有多個Value,而不是關系數據庫中為降低數據的冗余性要求實現的各個域必須是不相關的。LDAP中條目的組織一般按照地理位置和組織關系進行組織,非常的直觀。LDAP把數據存放在文件中,為提高效率可以使用基於索引的文件數據庫,而不是關系數據庫。類型的一個例子就是mail,其值將是一個電子郵件地址。
LDAP的信息是以樹型結構存儲的,在樹根一般定義國家(c=CN)或域名(dc=com),在其下則往往定義一個或多個組織 (organization)(o=Acme)或組織單元(organizational units) (ou=People)。一個組織單元可能包含諸如所有雇員、大樓內的所有打印機等信息。此外,LDAP支持對條目能夠和必須支持哪些屬性進行控制,這是有一個特殊的稱為對象類別(objectClass)的屬性來實現的。該屬性的值決定了該條目必須遵循的一些規則,其規定了該條目能夠及至少應該包含哪些屬性。例如:inetorgPerson對象類需要支持sn(surname)和cn(common name)屬性,但也可以包含可選的如郵件,電話號碼等屬性。
2. LDAP簡稱對應
- o– organization(組織-公司)
- ou – organization unit(組織單元-部門)
- c - countryName(國家)
- dc - domainComponent(域名)
- sn – suer name(真實名稱)
- cn - common name(常用名稱)
3.常見的目錄服務軟件
- X.500
- LDAP
- Actrive Directory,Microsoft公司
- NIS
4.AD介紹
.Net提供了專用類操作AD,本文詳細介紹使用C#操作AD的方法。
一、系統環境
系統環境:Windows Server 2008 R2, VS2010, .Net Framework 4.0
AD Server:LDAP的server IP
基本DN:OU=user,DC=Company,DC=com
用來登錄的管理員:Peter
密碼:ab#CD%1234
二、程序
1. 引用
.Net操作AD的類在命名空間System.DirectoryServices下,需要將該類引用進來。
2. 連接
要操作AD需首先連接AD,就象要操作數據先要連接數據庫一樣。
其中ADPath是要查詢組織單元的所在的LDAP,其格式為:LDAP:\\ OU=XX部門,OU=XX公司,DC=域名,DC=COM,如果連接到的AD是在服務器上那么格式寫成LDAP:\\XX.XX.XX.XX\ OU=XX部門,OU=XX公司,DC=域名,DC=COM(XX.XX.XX.XX為服務器IP);ADAccount和ADPwd為AD用戶的賬戶和密碼,如果是管理員則可以進行任何操作,普通只能進行查詢操作。
de.Path = "LDAP://AD服務器地址/OU=CompanyA,DC=contoso,DC=com"; de.Username = @"contoso\管理員賬號"; de.Password = "管理員密碼";
private static string DomainName = "VMEX"; private static string LDAPDomain = "DC=VMEX,DC=local"; private static string ADPath = "LDAP://DC=VMEX,DC=local"; //AD管理員帳號 private static string ADUser = "Administrator"; //AD管理員密碼 private static string ADPasssWord = "1234@abcd";
/// <summary>
/// 獲得DirectoryEntry對象實例,以管理員登陸AD
/// </summary>
/// <returns></returns>
private static DirectoryEntry GetDirectoryObject()
{
DirectoryEntry entry = null;
try
{
entry = new DirectoryEntry("LDAP://10.10.10.16", "Peter", " ab#CD%1234", AuthenticationTypes.Secure);
}
catch (Exception ex)
{
}
return entry;
}
3. 查詢
根據各種條件獲取具體的用戶。下例為根據公共名稱獲取對象。
/// <summary>
/// 根據用戶公共名稱取得用戶的 對象
/// </summary>
/// <param name="commonName">用戶公共名稱</param>
/// <returns>如果找到該用戶則返回用戶的對象,否則返回 null</returns>
public static DirectoryEntry GetDirectoryEntry(string commonName)
{
DirectoryEntry de = GetDirectoryObject();
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(&(objectCategory=person)(objectClass=user))(cn=" + commonName.Replace("\\", "") + "))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = deSearch.FindOne();
de = new DirectoryEntry(result.Path);
return de;
}
catch (Exception ex)
{
return null;
}
}
4. 修改用戶
修改查詢到的Entity的值,修改后將修改記錄保存到AD。注意有兩種保存屬性的方式。具體使用哪種請參考幫助。
1) 直接修改屬性
2) 通過invoke來觸發AD的內置函數
/// <summary>
/// 修改查詢到的用戶
/// </summary>
/// <param name="CommonName">通用名(displayName,系統中顯示的中文字)</param>
/// <param name="Account">帳戶名(如Peter)</param>
/// <param name="organizeName">組織單元名(資訊中心)</param>
/// <param name="password">密碼</param>
public static string ChangeADAccount(string CommonName, string Account, string password)
{
//獲取對應AD實體
DirectoryEntry user = GetDirectoryEntry( commonName);
try
{
ADHelper.SetProperty(user, " sAMAccountName ", Account);
user.Invoke("SetPassword", new object[] { password });
user.CommitChanges();
}
catch (Exception e)
{
throw e;
}
return user.Path;
}
/// <summary>
/// 設置指定的屬性值
/// </summary>
/// <param name="de"></param>
/// <param name="propertyName">屬性名稱?</param>
/// <param name="propertyValue">屬性值</param>
public static void SetProperty(DirectoryEntry de, string propertyName, string propertyValue)
{
if (de.Properties.Contains(propertyName))
{
if (String.IsNullOrEmpty(propertyValue))
{
de.Properties[propertyName].RemoveAt(0);
}
else
{
de.Properties[propertyName][0] = propertyValue;
}
}
else
{
if (!String.IsNullOrEmpty(propertyValue))
{
de.Properties[propertyName].Add(propertyValue);
}
}
}
5. 修改OU
1) 獲取OU
DirectoryEntry OUEntry = new DirectoryEntry(GetOrganizeNamePath(OUName), "Peter", " ab#CD%1234", AuthenticationTypes.Secure);
/// <summary>
/// 獲得OU的Path
/// </summary>
/// <param name="organizeUnit">OU名</param>
/// <returns></returns>
public static string GetOrganizeNamePath(string organizeUnit)
{
StringBuilder sb = new StringBuilder();
sb.Append(ADPath);
sb.Append("/");
return sb.Append(SplitOrganizeNameToDN(organizeUnit)).ToString();
}
2) 修改OU項
OUEntry.Rename("OU=" + newOUName);
OUEntry.CommitChanges();
3) 刪除OU
DirectoryEntry OUParent = OUEntry.Parent;
OUParent.Children.Remove(OUEntry);
OUParent.CommitChanges();
6. 修改組
1) 獲取組
/// <summary>
/// 獲取AD組
/// </summary>
/// <param name="groupName"></param>
/// <param name="organizeUnit"></param>
/// <returns></returns>
public static DirectoryEntry GetADGroupInOU(string groupName, string organizeUnit)
{
if (!String.IsNullOrEmpty(groupName))
{
DirectoryEntry de = new DirectoryEntry(GetOrganizeNamePath(organizeUnit) , "Peter", " ab#CD%1234", AuthenticationTypes.Secure); ;
DirectorySearcher deSearch = new DirectorySearcher(de);
deSearch.Filter = "(&(objectClass=group)(cn=" + groupName.Replace("\\", "") + "))";
deSearch.SearchScope = SearchScope.Subtree;
try
{
SearchResult result = deSearch.FindOne();
if (result != null)
{
de = new DirectoryEntry(result.Path, adminName, adminPassword);
}
else
{
return null;
}
return de;
}
catch (Exception ex)
{
return null;
}
}
else
{
return null;
}
}
2) 管理組成員
group.Properties["member"].Add(user.Properties["distinguishedName"].Value); group.Properties["member"].Remove(user.Properties["distinguishedName"].Value);
三、查看AD User屬性結果
在程序中修改了User屬性后我們要檢驗一下是否被修改了,有三種方式查看AD中User屬性:
1. Active Directory Users and Computers
打開Active Directory Users and Computers,選擇一個用戶,右鍵單擊該用戶選擇屬性顯示如下圖所示的屬性頁。在該屬性頁只能看到一些常用的屬性。

2. Exchange Management Console
打開Exchange Management Console,選擇一個用戶,右鍵單擊該用戶選擇屬性顯示如下圖所示的屬性頁。單擊Customer Attributes按鈕可以查看自定義的屬性。

3. adsiedit.msc
以上兩種方式所看到的屬性都不全,要看到所有屬性需使用adsiedit.msc工具。
在運行窗口中輸入adsiedit.msc后打開本工具。選擇一個用戶,右鍵單擊該用戶選擇屬性顯示如下圖所示的屬性頁。

