使用LDAP更改用户密码

时间:2015-11-04 21:54:55

标签: c# ldap change-password

这是我的代码

var fullName = ApplicationSettings.DefaultUser;
var userId = fullName.Substring(fullName.LastIndexOf(@"\", StringComparison.Ordinal) + 1).ToUpper(CultureInfo.InvariantCulture);
    try
    {

        DirectoryEntry entry = new DirectoryEntry("LDAP://ldapaddressstring", userId, existingPassword, AuthenticationTypes.Secure);

        DirectorySearcher search = new DirectorySearcher(entry);
        search.Filter = "(&(objectClass=user)(sAMAccountName=" + userId + "))";
        entry = search.FindOne().GetDirectoryEntry();
        entry.Invoke("ChangePassword", new object[] { existingPassword, newPassword });
    }
    catch (Exception ex)
    {

        //throw plain exception
        throw ex;      

    }

我收到了错误的用户名或密码错误。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

您是希望用户更改自己的密码,还是要将管理员重置为密码?

您是否获得了任何入境信息,或者您在致电FindOne时发生了错误?

这是我使用的代码,“Impersonator”是允许模拟域管理员帐户以确保适当权限的类。你应该能够找到它here

public ServiceResponse ChangePassword(string username, string oldPassword, string newPassword)
        {
            ServiceResponse response = new ServiceResponse();

            try
            {
                var entry = new DirectoryEntry(DomainUsersConnectionString, username, oldPassword);
                var nativeObject = entry.NativeObject;

                // Check passed. Can reset the password now
                entry = RootDirectoryEntry;
                var user = FindUserInDirectoryEntry(username, entry);
                response = SetPassword(user, newPassword);
                user.Close();
            }
            catch (DirectoryServicesCOMException ex)
            {
                response.Status = Status.Error;
                response.Message = ex.ExtendedErrorMessage;
                m_Logger.Error("Failed to change password for user {0}: {1} - {2}", username, ex.ExtendedErrorMessage, (ex.InnerException ?? ex));
            }
            catch (Exception ex)
            {
                response.Status = Status.Error;
                response.Message = ex.Message;
                m_Logger.Error("Failed to change password for user {0}: {1} -{2}", username, ex.Message, (ex.InnerException ?? ex));
            }
            return response;
        }



        /// <summary>
        /// Finds the user in directory entry.
        /// </summary>
        /// <param name="username">The username.</param>
        /// <param name="dirEntry">The dir entry.</param>
        /// <returns></returns>
        protected static DirectoryEntry FindUserInDirectoryEntry(string username, DirectoryEntry dirEntry)
        {
            // rip off Domain name if username contains it
            string domainName = String.Format(@"{0}\", DomainName).ToLowerInvariant();
            username = username.Replace(domainName, "");
            DirectorySearcher searcher = new DirectorySearcher(dirEntry)
            {
                Filter = String.Format("(samAccountName={0})", username)
            };
            var searchResult = searcher.FindOne();
            if (searchResult != null)
            {
                DirectoryEntry user = searchResult.GetDirectoryEntry();
                return user;
            }
            return null;
        }



        private ServiceResponse SetPassword(DirectoryEntry user, string password)
        {
            ServiceResponse response = new ServiceResponse();

            try
            {
                using (var impersonator = new Impersonator(DomainAdminUsername, DomainName, DomainAdminPassword))
                {
                    user.Invoke("SetPassword", new object[] { password });
                    user.Properties["LockOutTime"].Value = 0; //unlock account
                    user.CommitChanges();
                }
                response.Status = Status.Success;
            }
            catch (DirectoryServicesCOMException ex)
            {
                response.Status = Status.Error;
                response.Message = ex.ExtendedErrorMessage;
                m_Logger.Error("SetPassword failed for user {0}: {1}", user.Name, ex.ExtendedErrorMessage);
            }
            catch (Exception ex)
            {
                response.Status = Status.Error;
                response.Message = ex.Message;
                m_Logger.Error("SetPassword failed for user {0} by {1} at {2}: {3}: {4}", user.Name, 
                    DomainAdminUsername, DomainName,
                    ex.Message, (ex.InnerException ?? ex).ToString());
            }

            return response;
        }

注意事项可能会影响您:

  1. 删除域名(如果存在)
  2. 检索“NativeObject”似乎对缓存/连接有影响
  3. 这是使用需要"Reset Password extended control access right"
  4. 的“SetPassword”