C# Active Directory 调用 "ChangePassword" 无法联系域
C# Active Directory Invoke "ChangePassword" cannot contact domain
我将以下代码作为我的 Active Directory 用户的 Web 应用程序的一部分,以便能够更新他们的密码(同时用于 Active Directory 和 gmail)。我在 System.DirectoryServices.AccountManagement.
中使用 C#
此代码一直有效到 昨天
try
{
State.log.WriteLine("Connecting LDAP.");
string ldapPath = "LDAP://192.168.76.3";
DirectoryEntry directionEntry = new DirectoryEntry(ldapPath, domainName + "\" + userName, currentPassword);
if (directionEntry != null)
{
DirectorySearcher search = new DirectorySearcher(directionEntry);
State.log.WriteLine("LDAP Connected, searching directory for SAMAccountName");
search.Filter = "(SAMAccountName=" + userName + ")";
SearchResult result = search.FindOne();
if (result != null)
{
State.log.WriteLine("Getting User Entry.");
DirectoryEntry userEntry = result.GetDirectoryEntry();
if (userEntry != null)
{
State.log.WriteLine("Setting Password");
if (force)
{
userEntry.Invoke("SetPassword", new[] { newPassword });
}
else
{
userEntry.Invoke("ChangePassword", new object[] { currentPassword, newPassword });
}
userEntry.CommitChanges();
State.log.WriteLine("Changes Committed to ActiveDirectory.");
}
else
{
State.log.WriteLine("Could not get user Entry...");
}
}
else
{
State.log.WriteLine("Search returned no results.");
}
}
else
{
State.log.WriteLine("Could not connect to LDAP with given username and passwd");
}
}
从昨天开始,这段代码就上线了:
userEntry.Invoke("ChangePassword", new object[] { currentPassword, newPassword });
然后抛出以下异常:
[8:37:00 AM] : Password Requirements Met.
[8:37:00 AM] : Connecting LDAP.
[8:37:00 AM] : LDAP Connected, searching directory for SAMAccountName
[8:37:01 AM] : Getting User Entry.
[8:37:01 AM] : Setting Password
[8:37:01 AM] : Failed to reset Windows Password for jason.
Exception has been thrown by the target of an invocation.
The system cannot contact a domain controller to service the authentication request. Please try again later. (Exception from HRESULT: 0x800704F1)
使用“SetPassword”的“force”选项仍然可以正常工作,但非管理员用户可以调用的“ChangePassword”方法不能。
本月早些时候,Microsoft released a security patch 解决了密码更改领域的一些漏洞。具体来说,此更新阻止了在更改密码时 Kerberos 身份验证失败后回退到 NTLM 身份验证。
您可能想阅读有关更新的更多信息 here。
改变userPrincipal.ChangePassword("Old pass","New Pass");至 userPrincipal.SetPassword(model.NewPassword);
Microsoft 已更新这篇文章:https://support.microsoft.com/en-us/kb/3177108。在这里,他们为我们提供了由原始 "fixes" 造成的问题以及使用 Kerberos 和自助服务密码重置的一些技巧。
自 2016 年 10 月 11 日起,Microsoft 重新发布了与 https://technet.microsoft.com/en-us/library/security/ms16-101.aspx 相关的补丁,以解决导致的问题通过原始更新(您可以在 https://support.microsoft.com/en-us/kb/3177108 中阅读,包括您无法再更改本地帐户密码的事实)。
我找到了一个解决方法,但忘了 post 它。我所做的是使用上面的代码对用户进行身份验证,然后调用我的 "ForceChangePassword" 方法:
public static void ForceChangeADPassword(String username, String newPassword)
{
String DN = "";
try
{
DN = GetObjectDistinguishedName(objectClass.user, returnType.distinguishedName, username, DOMAIN_CONTROLLER_IP);
}
catch(Exception e)
{
throw new PasswordException(String.Format("Could not find AD User {0}", username), e);
}
if(DN.Equals(""))
throw new PasswordException(String.Format("Could not find AD User {0}", username));
DirectoryEntry userEntry = new DirectoryEntry(DN.Replace("LDAP://", LdapRootPath), "accounts", AcctPwd);
userEntry.Invoke("SetPassword", new object[] { newPassword });
userEntry.Properties["LockOutTime"].Value = 0;
userEntry.CommitChanges();
userEntry.Close();
}
我将以下代码作为我的 Active Directory 用户的 Web 应用程序的一部分,以便能够更新他们的密码(同时用于 Active Directory 和 gmail)。我在 System.DirectoryServices.AccountManagement.
中使用 C#此代码一直有效到 昨天
try
{
State.log.WriteLine("Connecting LDAP.");
string ldapPath = "LDAP://192.168.76.3";
DirectoryEntry directionEntry = new DirectoryEntry(ldapPath, domainName + "\" + userName, currentPassword);
if (directionEntry != null)
{
DirectorySearcher search = new DirectorySearcher(directionEntry);
State.log.WriteLine("LDAP Connected, searching directory for SAMAccountName");
search.Filter = "(SAMAccountName=" + userName + ")";
SearchResult result = search.FindOne();
if (result != null)
{
State.log.WriteLine("Getting User Entry.");
DirectoryEntry userEntry = result.GetDirectoryEntry();
if (userEntry != null)
{
State.log.WriteLine("Setting Password");
if (force)
{
userEntry.Invoke("SetPassword", new[] { newPassword });
}
else
{
userEntry.Invoke("ChangePassword", new object[] { currentPassword, newPassword });
}
userEntry.CommitChanges();
State.log.WriteLine("Changes Committed to ActiveDirectory.");
}
else
{
State.log.WriteLine("Could not get user Entry...");
}
}
else
{
State.log.WriteLine("Search returned no results.");
}
}
else
{
State.log.WriteLine("Could not connect to LDAP with given username and passwd");
}
}
从昨天开始,这段代码就上线了:
userEntry.Invoke("ChangePassword", new object[] { currentPassword, newPassword });
然后抛出以下异常:
[8:37:00 AM] : Password Requirements Met.
[8:37:00 AM] : Connecting LDAP.
[8:37:00 AM] : LDAP Connected, searching directory for SAMAccountName
[8:37:01 AM] : Getting User Entry.
[8:37:01 AM] : Setting Password
[8:37:01 AM] : Failed to reset Windows Password for jason.
Exception has been thrown by the target of an invocation.
The system cannot contact a domain controller to service the authentication request. Please try again later. (Exception from HRESULT: 0x800704F1)
使用“SetPassword”的“force”选项仍然可以正常工作,但非管理员用户可以调用的“ChangePassword”方法不能。
本月早些时候,Microsoft released a security patch 解决了密码更改领域的一些漏洞。具体来说,此更新阻止了在更改密码时 Kerberos 身份验证失败后回退到 NTLM 身份验证。
您可能想阅读有关更新的更多信息 here。
改变userPrincipal.ChangePassword("Old pass","New Pass");至 userPrincipal.SetPassword(model.NewPassword);
Microsoft 已更新这篇文章:https://support.microsoft.com/en-us/kb/3177108。在这里,他们为我们提供了由原始 "fixes" 造成的问题以及使用 Kerberos 和自助服务密码重置的一些技巧。
自 2016 年 10 月 11 日起,Microsoft 重新发布了与 https://technet.microsoft.com/en-us/library/security/ms16-101.aspx 相关的补丁,以解决导致的问题通过原始更新(您可以在 https://support.microsoft.com/en-us/kb/3177108 中阅读,包括您无法再更改本地帐户密码的事实)。
我找到了一个解决方法,但忘了 post 它。我所做的是使用上面的代码对用户进行身份验证,然后调用我的 "ForceChangePassword" 方法:
public static void ForceChangeADPassword(String username, String newPassword)
{
String DN = "";
try
{
DN = GetObjectDistinguishedName(objectClass.user, returnType.distinguishedName, username, DOMAIN_CONTROLLER_IP);
}
catch(Exception e)
{
throw new PasswordException(String.Format("Could not find AD User {0}", username), e);
}
if(DN.Equals(""))
throw new PasswordException(String.Format("Could not find AD User {0}", username));
DirectoryEntry userEntry = new DirectoryEntry(DN.Replace("LDAP://", LdapRootPath), "accounts", AcctPwd);
userEntry.Invoke("SetPassword", new object[] { newPassword });
userEntry.Properties["LockOutTime"].Value = 0;
userEntry.CommitChanges();
userEntry.Close();
}