C# 操做LDAP查找組或人員信息編程
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.DirectoryServices; /// <summary> ///ADUtil 的摘要說明 /// </summary> public class ADUtil { // LDAP地址 例如:LDAP://my.com.cn private const string LDAP_HOST = "LDAP://my.com.cn"; // 具備LDAP管理權限的特殊賬號 private const string USER_NAME = "account"; // 具備LDAP管理權限的特殊賬號的密碼 private const string PASSWORD = "password"; public ADUtil() { // //TODO: 在此處添加構造函數邏輯 // } /** * 向某個組添加人員 * groupName 組名稱 * userName 人員域賬號 **/ public static void addGroupMember(string groupName, string userName) { DirectoryEntry group = getGroupByName(groupName); group.Username = USER_NAME; group.Password = PASSWORD; group.Properties["member"].Add(getUserDNByName(userName)); group.CommitChanges(); } /** * 從某個組移出指定的人員 * groupName 組名稱 * userName 人員域賬號 **/ public static void removeGroupMember(string groupName, string userName) { DirectoryEntry group = getGroupByName(groupName); group.Username = USER_NAME; group.Password = PASSWORD; group.Properties["member"].Remove(getUserDNByName(userName)); group.CommitChanges(); } /** * 獲取指定人員的域信息 * name 人員域賬號 **/ public static object getUserDNByName(string name) { DirectorySearcher userSearch = new DirectorySearcher(LDAP_HOST); userSearch.SearchRoot = new DirectoryEntry(LDAP_HOST, USER_NAME, PASSWORD); userSearch.Filter = "(SAMAccountName=" + name + ")"; SearchResult user = userSearch.FindOne(); if (user == null) { throw new Exception("請確認域用戶是否正確"); } return user.Properties["distinguishedname"][0]; } /** * 獲取指定域組的信息 * name 組名稱 **/ public static DirectoryEntry getGroupByName(string name) { DirectorySearcher search = new DirectorySearcher(LDAP_HOST); search.SearchRoot = new DirectoryEntry(LDAP_HOST, USER_NAME, PASSWORD); search.Filter = "(&(cn=" + name + ")(objectClass=group))"; search.PropertiesToLoad.Add("objectClass"); SearchResult result = search.FindOne(); DirectoryEntry group; if (result != null) { group = result.GetDirectoryEntry(); } else { throw new Exception("請確認AD組列表是否正確"); } return group; } }
C# LDAP 管理(建立新用戶)服務器
今天用C#實現了一套LDAP域帳號的建立和查詢,感覺挺多。dom
算是第一次接觸LDAP吧,以前曾經作了一個登陸的驗證,就是查詢功能,那個相對比較簡單,用到了一個方法就搞定了。ide
此次的需求是要用編程的方式建立域帳號,實現域登錄。函數
首先回顧一下以前查詢用到的代碼:測試
public static bool TryAuthenticate(string userName, string password) { string domain = "litb-inc.com"; bool isLogin = false; try { DirectoryEntry entry = new DirectoryEntry(string.Format("LDAP://{0}", domain), userName, password); entry.RefreshCache(); DBLog.Debug("check success"); isLogin = true; } catch (Exception ex) { DBLog.Debug("域驗證拋出異常 :" + ex.Message + ex.InnerException); isLogin = false; } return isLogin; }
這是驗證指定用戶是否在域裏認證經過。ui
接下來,實現建立域帳戶的操做。在網上找到了一個操做類:spa
using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.DirectoryServices; using System.Linq; using System.Text; using System.Text.RegularExpressions; namespace Litb.HRExtension { public static class AdHerlp { #region 建立AD鏈接 /// <summary> /// 建立AD鏈接 /// </summary> /// <returns></returns> public static DirectoryEntry GetDirectoryEntry() { DirectoryEntry de = new DirectoryEntry(); de.Path = "LDAP://testhr.com/CN=Users,DC=testhr,DC=com"; de.Username = @"administrator"; de.Password = "litb20!!"; return de; //DirectoryEntry entry = new DirectoryEntry("LDAP://testhr.com", "administrator", "litb20!!", AuthenticationTypes.Secure); //return entry; } #endregion #region 獲取目錄實體集合 /// <summary> /// /// </summary> /// <param name="DomainReference"></param> /// <returns></returns> public static DirectoryEntry GetDirectoryEntry(string DomainReference) { DirectoryEntry entry = new DirectoryEntry("LDAP://testhr.com" + DomainReference, "administrator", "litb20!!", AuthenticationTypes.Secure); return entry; } #endregion } //AD操做類 //myDirectory.cs public class myDirectory { /// <summary> /// 判斷用戶是否存在 /// </summary> /// <param name="UserName"></param> /// <returns></returns> public bool UserExists(string UserName) { DirectoryEntry de = AdHerlp.GetDirectoryEntry(); DirectorySearcher deSearch = new DirectorySearcher(); deSearch.SearchRoot = de; deSearch.Filter = "(&(objectClass=user) (cn=" + UserName + "))"; SearchResultCollection results = deSearch.FindAll(); if (results.Count == 0) { return false; } else { return true; } } /// <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 (PropertyValue != null) { if (de.Properties.Contains(PropertyName)) { de.Properties[PropertyName][0] = PropertyValue; } else { de.Properties[PropertyName].Add(PropertyValue); } } } /// <summary> /// 生成隨機密碼 /// </summary> /// <returns></returns> public string SetSecurePassword() { //RandomPassword rp = new RandomPassword(); return "qwe123!@#"; } /// <summary> /// 設置用戶新密碼 /// </summary> /// <param name="path"></param> public void SetPassword(DirectoryEntry newuser) { //DirectoryEntry usr = new DirectoryEntry(); //usr.Path = path; //usr.AuthenticationType = AuthenticationTypes.Secure; //object[] password = new object[] { SetSecurePassword() }; //object ret = usr.Invoke("SetPassword", password); //usr.CommitChanges(); //usr.Close(); newuser.AuthenticationType = AuthenticationTypes.Secure; object[] password = new object[] { SetSecurePassword() }; object ret = newuser.Invoke("SetPassword", password); newuser.CommitChanges(); newuser.Close(); } /// <summary> /// 啓用用戶賬號 /// </summary> /// <param name="de"></param> private static void EnableAccount(DirectoryEntry de) { //UF_DONT_EXPIRE_PASSWD 0x10000 int exp = (int)de.Properties["userAccountControl"].Value; de.Properties["userAccountControl"].Value = exp | 0x0001; de.CommitChanges(); //UF_ACCOUNTDISABLE 0x0002 int val = (int)de.Properties["userAccountControl"].Value; de.Properties["userAccountControl"].Value = val & ~0x0002; de.CommitChanges(); } /// <summary> /// 添加用戶到組 /// </summary> /// <param name="de"></param> /// <param name="deUser"></param> /// <param name="GroupName"></param> public static void AddUserToGroup(DirectoryEntry de, DirectoryEntry deUser, string GroupName) { DirectorySearcher deSearch = new DirectorySearcher(); deSearch.SearchRoot = de; deSearch.Filter = "(&(objectClass=group) (cn=" + GroupName + "))"; SearchResultCollection results = deSearch.FindAll(); bool isGroupMember = false; if (results.Count > 0) { DirectoryEntry group = AdHerlp.GetDirectoryEntry(results[0].Path); object members = group.Invoke("Members", null); foreach (object member in (IEnumerable)members) { DirectoryEntry x = new DirectoryEntry(member); if (x.Name != deUser.Name) { isGroupMember = false; } else { isGroupMember = true; break; } } if (!isGroupMember) { group.Invoke("Add", new object[] { deUser.Path.ToString() }); } group.Close(); } return; } /// <summary> /// 建立一個新用戶 /// </summary> /// <param name="employeeID"></param> /// <param name="name"></param> /// <param name="login"></param> /// <param name="email"></param> /// <param name="group"></param> public void CreateNewUser(string employeeID, string name, string login, string email, string group) { //Catalog catalog = new Catalog(); DirectoryEntry de = AdHerlp.GetDirectoryEntry(); /// 1. Create user account DirectoryEntries users = de.Children; DirectoryEntry newuser = users.Add("CN=" + login, "user"); /// 2. Set properties SetProperty(newuser, "employeeID", employeeID); SetProperty(newuser, "givenname", name); SetProperty(newuser, "SAMAccountName", login); SetProperty(newuser, "userPrincipalName", login); SetProperty(newuser, "mail", email); SetProperty(newuser, "Description", "Create User By HrESS System"); newuser.CommitChanges(); /// 3. Set password newuser.AuthenticationType = AuthenticationTypes.Secure; object[] password = new object[] { SetSecurePassword() }; object ret = newuser.Invoke("SetPassword", password); newuser.CommitChanges(); //newuser.Close(); //SetPassword(newuser); //newuser.CommitChanges(); /// 4. Enable account EnableAccount(newuser); /// 5. Add user account to groups AddUserToGroup(de, newuser, group); /// 6. Create a mailbox in Microsoft Exchange //GenerateMailBox(login); newuser.Close(); de.Close(); } /// <summary> /// 禁用一個賬號 /// </summary> /// <param name="EmployeeID"></param> public void DisableAccount(string EmployeeID) { DirectoryEntry de = AdHerlp.GetDirectoryEntry(); DirectorySearcher ds = new DirectorySearcher(de); ds.Filter = "(&(objectCategory=Person)(objectClass=user)(employeeID=" + EmployeeID + "))"; ds.SearchScope = SearchScope.Subtree; SearchResult results = ds.FindOne(); if (results != null) { DirectoryEntry dey = AdHerlp.GetDirectoryEntry(results.Path); int val = (int)dey.Properties["userAccountControl"].Value; dey.Properties["userAccountControl"].Value = val | 0x0002; dey.Properties["msExchHideFromAddressLists"].Value = "TRUE"; dey.CommitChanges(); dey.Close(); } de.Close(); } /// <summary> /// 修改用戶信息 /// </summary> /// <param name="employeeID"></param> /// <param name="department"></param> /// <param name="title"></param> /// <param name="company"></param> public void ModifyUser(string employeeID, string department, string title, string company) { DirectoryEntry de = AdHerlp.GetDirectoryEntry(); DirectorySearcher ds = new DirectorySearcher(de); ds.Filter = "(&(objectCategory=Person)(objectClass=user)(employeeID=" + employeeID + "))"; ds.SearchScope = SearchScope.Subtree; SearchResult results = ds.FindOne(); if (results != null) { DirectoryEntry dey = AdHerlp.GetDirectoryEntry(results.Path); SetProperty(dey, "department", department); SetProperty(dey, "title", title); SetProperty(dey, "company", company); dey.CommitChanges(); dey.Close(); } de.Close(); } /// <summary> /// 檢驗Email格式是否正確 /// </summary> /// <param name="mail"></param> /// <returns></returns> public bool IsEmail(string mail) { Regex mailPattern = new Regex(@"\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*"); return mailPattern.IsMatch(mail); } /// <summary> /// 搜索被修改過的用戶 /// </summary> /// <param name="fromdate"></param> /// <returns></returns> public DataTable GetModifiedUsers(DateTime fromdate) { DataTable dt = new DataTable(); dt.Columns.Add("EmployeeID"); dt.Columns.Add("Name"); dt.Columns.Add("Email"); DirectoryEntry de = AdHerlp.GetDirectoryEntry(); DirectorySearcher ds = new DirectorySearcher(de); StringBuilder filter = new StringBuilder(); filter.Append("(&(objectCategory=Person)(objectClass=user)(whenChanged>="); filter.Append(ToADDateString(fromdate)); filter.Append("))"); ds.Filter = filter.ToString(); ds.SearchScope = SearchScope.Subtree; SearchResultCollection results = ds.FindAll(); foreach (SearchResult result in results) { DataRow dr = dt.NewRow(); DirectoryEntry dey = AdHerlp.GetDirectoryEntry(result.Path); dr["EmployeeID"] = dey.Properties["employeeID"].Value; dr["Name"] = dey.Properties["givenname"].Value; dr["Email"] = dey.Properties["mail"].Value; dt.Rows.Add(dr); dey.Close(); } de.Close(); return dt; } /// <summary> /// 格式化AD的時間 /// </summary> /// <param name="date"></param> /// <returns></returns> public string ToADDateString(DateTime date) { string year = date.Year.ToString(); int month = date.Month; int day = date.Day; StringBuilder sb = new StringBuilder(); sb.Append(year); if (month < 10) { sb.Append("0"); } sb.Append(month.ToString()); if (day < 10) { sb.Append("0"); } sb.Append(day.ToString()); sb.Append("000000.0Z"); return sb.ToString(); } } }
有了這個操做類,就能夠進行域帳號的建立了,調用示例:code
Console.WriteLine("Begin CreateNewUser"); string name = "wj" + System.Guid.NewGuid().ToString().Substring(0, 5); string id = System.Guid.NewGuid().ToString().Substring(0, 5);my.CreateNewUser(id, name, name, name + "@testhr.com", "testhr.com/Users"); Console.WriteLine("域用戶名建立成功:" + name);
注意域帳號的用戶名不能有相似-,下劃線之類的特殊字符。orm
在最初嘗試的時候,建立對象 DirectoryEntry的時候老是有問題,最終這兩種方式都是有效的:
DirectoryEntry de = new DirectoryEntry(); de.Path = "LDAP://testhr.com/CN=Users,DC=testhr,DC=com"; de.Username = @"administrator"; de.Password = "litb20!!"; return de; DirectoryEntry entry = new DirectoryEntry("LDAP://testhr.com", "administrator", "litb20!!", AuthenticationTypes.Secure); return entry;
其次,在建立完用戶之後,須要設置用戶的密碼,這個方法老是報錯,後來通過檢查,發現若是隻傳遞path字符串,是不行的,必須操做現有對象的Invoke方法才能夠!
或者傳遞對象引用。
最終,成功建立了域帳戶。
在測試的時候,同一臺機器加入了多個帳號後,就會有問題,報出相似這樣的錯誤:
最終,能夠經過在服務器上刪除這臺電腦的方式來解決,或者重命名本地計算機名稱。
1、建立LDAP鏈接
2、準備用戶擁有的屬性
3、 刪除用戶的信息
LdapConnection conn = new LdapConnection(); conn.Connect("192.168.3.112", 389); string dn = "CN=Administrator,CN=Users,DC=baiyi,DC=com"; conn.Bind(dn, "etimes2011@"); sbyte[] mysbyte = new sbyte[caByte.Length]; for (int i = 0; i < caByte.Length; i++) { if (caByte[i] > 127) { mysbyte[i] = (sbyte)(caByte[i] - 256); } else { mysbyte[i] = (sbyte)(caByte[i]); } } LdapAttribute attribute = new LdapAttribute("userCertificate", mysbyte); string user = "CN=foodean,CN=Users,DC=baiyi,DC=com"; conn.Modify(user, new LdapModification(LdapModification.DELETE, attribute));//注意這裏使用的是DELETE conn.Disconnect();