0

好吧,我正在使用 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(因为这不尊重密码历史记录)。

4

1 回答 1

0

LDAP_SERVER_POLICY_HINTS_OID控件仅强制执行密码历史限制,这意味着您只是在防止密码重用,如果您首先生成随机密码,这应该不是问题。

要根据密码复杂性设置测试新密码,您需要访问安装在域控制器上的密码过滤器。

否则,您将需要使用SetPassword- 它会强制执行复杂性要求,但不会强制执行密码历史记录。

于 2015-05-21T00:02:41.280 回答