Windows AD 无法通过代码重置密码

Windows AD unable to reset password from code

从尝试重置 AD 用户密码并使用相同密码进一步从其他服务登录的代码。但是 AD 没有对用户进行身份验证。 在 AD 中,我们正在更新代码中的 userPasswordholcimIsRegistereduserAccountControl 属性以重置密码。

当我们从 ADSI 手动重置 AD 用户密码时(右键单击用户 -> 转到重置密码→重置密码)然后 AD 正在使用新密码对用户进行身份验证。 userPasswordunicodePwd 属性都没有更新。

我们尝试从 ADSI 和代码中更新 unicodePwd 属性,但它不允许用户从我们观察到的代码中更新它的值

[LDAP: error code 53 - 0000001F: SvcErr: DSID-031A12D2, problem 5003 (WILL_NOT_PERFORM)]

我们比较了之前的用户详细信息并从 ADSI 重置密码,发现很少有详细信息正在获取 已更新(BadLogonCount:0badPasswordTime:0badPwdCount:0lastLogoff:0lastLogon:0logonCount:0ModifiedmodifyTimeStampmsDS-User-Account-Control-ComputedPasswordExpired:falsePasswordLastSetuSNChangedwhenChanged).

当我们尝试从 ADSI 修改 usnChanged 时,msDS-User-Account-Control-Computed 然后观察到这两个属性无法从 ADSI 和它提供的代码中编辑 SchemaViolationException。对于 passwordExpiredbadLogonCount 属性,我们在从代码和 ADSI 修改它时面临 NoSuchAttributeException 这两个属性丢失。

我们还可以怎样做?

要重置密码,请更新 unicodePwd 属性。 The documentation 告诉您一些要求:

  1. 新密码必须采用特定格式:包含在double-quotes中然后转换为UTF-16编码,以及
  2. 连接必须加密。

This page 在 Java 中有一个如何执行此操作的示例,我已将其粘贴在下方。它没有讨论加密,但您可以使用 LDAP over SSL (LDAPS),您可以使用 LDAPS:// 而不是仅 LDAP:// 来实现。这假定 AD 服务器已正确设置 LDAPS,并且您没有阻止 LDAPS 端口 (636) 的防火墙。

/**
 * Update User Password in Microsoft Active Directory
 * @param username
 * @param password
 */
public void updateUserPassword(String username, String password)
{
    try
    {
        System.out.println("updating password...\n");
        String quotedPassword = "\"" + password + "\"";
        char unicodePwd[] = quotedPassword.toCharArray();
        byte pwdArray[] = new byte[unicodePwd.length * 2];
        for (int i = 0; i < unicodePwd.length; i++)
        {
        pwdArray[i * 2 + 1] = (byte) (unicodePwd[i] >>> 8);
        pwdArray[i * 2 + 0] = (byte) (unicodePwd[i] & 0xff);
        }
        System.out.print("encoded password: ");
        for (int i = 0; i < pwdArray.length; i++)
        {
        System.out.print(pwdArray[i] + " ");
        }
        System.out.println();
        ModificationItem[] mods = new ModificationItem[1];
        mods[0] = new ModificationItem(DirContext.REPLACE_ATTRIBUTE, new BasicAttribute("UnicodePwd", pwdArray));
        ldapContext.modifyAttributes("cn=" + username + BASE_NAME, mods);
    }
    catch (Exception e)
    {
        System.out.println("update password error: " + e);
    }
}