好吧,我正在使用 DirectoryEntry 和 LdapConnection 在我们强制执行密码最低年龄和历史策略的情况下重置密码。当有人忘记密码时,您希望他们能够将密码重置为不违反密码历史记录的内容。作为替代解决方案,可以使用“SetPassword”并将密码重置为生成的值,然后强制用户在下次登录时更改密码。这在我们的场景中是不可能的。因此,我在 technet 上关注这篇博文,并尝试使用 LDap 扩展控件来通过尊重密码历史记录来重置密码。简而言之,它只是一次又一次地更改为相同的密码而没有抱怨。我的代码如下:
private static void PasswordChanger(DirectoryConnection ldapCon,
string distinguishedName,
string passwordToSet = null)
{
// the 'unicodePWD' attribute is used to handle pwd handling requests
// modification control for the replace operation
var damReplace = new DirectoryAttributeModification
{
Name = "unicodePwd"
};
// value to be send with the request
damReplace.Add(Encoding.Unicode.GetBytes(String.Format("\"{0}\"", passwordToSet)));
// this is a replace operation
damReplace.Operation = DirectoryAttributeOperation.Replace;
// combine modification controls
var damList = new DirectoryAttributeModification[]
{
damReplace
};
// init modify request
var modifyRequest = new ModifyRequest(distinguishedName, damList);
// the actual extended control OID
const string ldapServerPolicyHintsOid = "1.2.840.113556.1.4.2239";
// build value utilizing berconverter
var value = BerConverter.Encode("{i}", new object[] { 0x1 });
// init exetnded control. The variable name represts the actual extended control name.
var LDAP_SERVER_POLICY_HINTS_OID = new DirectoryControl(ldapServerPolicyHintsOid,
value, false, true);
// add extended control to modify request
modifyRequest.Controls.Add(LDAP_SERVER_POLICY_HINTS_OID);
/* send the request into the LDAPConnection and receive the response */
var result = ldapCon.SendRequest(modifyRequest);
}
对密码更改器的调用如下所示,
using (var domain = Domain.GetDomain(new DirectoryContext(
DirectoryContextType.DirectoryServer,
ActiveDirectoryInstance,
request.ServiceAccountName,
request.ServiceAccountPassword)))
using (var directoryEntry = domain.GetDirectoryEntry())
using (var directorySearcher = new DirectorySearcher(directoryEntry))
using (var conn = new LdapConnection(new LdapDirectoryIdentifier(ActiveDirectoryInstance),
new NetworkCredential(request.ServiceAccountName,
request.ServiceAccountPassword,
ActiveDirectoryInstance),
AuthType.Ntlm))
{
...
...
PasswordChanger(....)
...
...
}
编辑:
这与此处解释的场景有关
https://support.microsoft.com/en-us/kb/2386717/
RE 我对“作为替代解决方案的评论”,可以使用“SetPassword”并将密码重置为生成的值,然后强制用户在下次登录时更改它。
我们不能在我们的场景中这样做,因为我们启用了密码历史记录和最小年龄限制(24 小时)。因此,我不能在用户上下文中使用 ChangePassword,在管理员上下文中使用 SetPassword(因为这不尊重密码历史记录)。