C# LDAP 管理(创建新用户)

来源:互联网 发布:ubuntu什么系统 编辑:程序博客网 时间:2024/06/05 17:03

今天用C#实现了一套LDAP域账号的创建和查询,感受挺多。

算是第一次接触LDAP吧,之前曾经做了一个登录的验证,就是查询功能,那个相对比较简单,用到了一个方法就搞定了。

这次的需求是要用编程的方式创建域账号,实现域登陆。


首先回顾一下之前查询用到的代码:

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

这是验证指定用户是否在域里认证通过。


接下来,实现创建域账户的操作。在网上找到了一个操作类:


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();        }    }}

有了这个操作类,就可以进行域账号的创建了,调用示例:

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);

注意域账号的用户名不能有类似-,下划线之类的特殊字符。


在最初尝试的时候,创建对象 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方法才可以!

或者传递对象引用。


最终,成功创建了域账户。


在测试的时候,同一台机器加入了多个账号后,就会有问题,报出类似这样的错误:


最终,可以通过在服务器上删除这台电脑的方式来解决,或者重命名本地计算机名称。





原创粉丝点击