与LDAP
问题描述:
修改用户密码这是我的代码与LDAP
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;
}
我越来越坏用户名或密码错误。有任何想法吗?
答
检索“NativeObject”似乎对缓存的作用
你想让用户改变他们自己的密码,或者管理员要重置它吗?
您是否收到任何输入内容,或者当您调用FindOne时发生错误?
这是我使用的代码,“模仿者”是允许冒充域管理员帐户以确保适当权限的类。你应该能够找到它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;
}
注意事项可能会影响你:
如果存在- 删除域名/连接
- 这是使用“SetPassword”这需要"Reset Password extended control access right"
谢谢罗杰。我需要用户能够更改自己的密码,最好不需要任何第三方课程。这可能吗?我的印象是这样的。 – sarsnake
是的,您应该能够放弃Impersonator(无论如何可以自由使用的源代码)并交换到ChangePassword而不是SetPassword。主要问题应该是:什么是例外?它可能是您声明/分配条目的位置,或者您调用ChangePassword的位置 –