ActiveDirectory:重置密码以兑现密码历史记录

时间:2015-05-20 23:35:59

标签: c# active-directory directoryentry ldapconnection

我正在使用DirectoryEntry和LdapConnection在我们实施密码最小年龄和历史记录策略的情况下重置密码。当有人忘记密码时,您希望他们能够将密码重置为不违反密码历史记录的密码。作为替代解决方案,可以使用" SetPassword"并将密码重置为生成的值,然后强制用户在下次登录时更改密码。在我们的场景中这是不可能的。因此,我在technet中关注this blog post并尝试通过尊重密码历史来重置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/

重新评论"作为替代解决方案,可以使用" SetPassword"并将密码重置为生成的值,然后强制用户在下次登录时进行更改。"

我们无法在我们的方案中执行此操作,因为我们已启用密码历史记录和最低年龄限制(24小时)。因此,我无法在用户上下文中使用ChangePassword,在管理上下文中使用SetPassword(因为它不会尊重密码历史记录)。

1 个答案:

答案 0 :(得分:0)

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

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

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