以编程方式确定 AD 密码策略

Chr*_* P. 5 c# active-directory

我一直在使用System.DirectoryService(ADSI) 类和方法在 Active Directory 中创建和更改用户。

最近我们添加了一项功能,允许用户通过系统设置自己的密码。但是,SetPassword当密码策略集不接受密码时,使用该方法会引发异常。

userEntry.Invoke("SetPassword", new object[] {password});
Run Code Online (Sandbox Code Playgroud)

我的问题是:在尝试使用 SetPassword 方法之前,如何检查密码是否符合密码策略?

我在这篇文章中读到,您可以从根域节点获取密码策略设置,但是我在哪里可以阅读有关每个属性含义的更多信息?例如,完成“复杂性”策略需要哪些字符?

一旦我知道这一点,我就可以实现我自己的密码检查方法,但由于这是一种容易出错的方法,我宁愿使用内置检查并为用户提供有关其密码错误的适当信息。

Ian*_*oyd 1

您想要的 API 函数是NetValidatePasswordPolicy

它有以下三种运行模式:

  • NetValidateAuthentication:如果您正在验证用户身份;因此该函数可以检查密码过期策略、错误登录尝试、帐户锁定、错误登录尝试等
  • NetValidatePasswordChange:如果用户正在更改密码;因此该函数可以检查锁定或密码策略

以及您想要的模式:

  • NetValidatePasswordReset:您是管理员,正在重置用户密码;它仅检查密码复杂性。

我将尝试即时从另一种语言转码为 C#;但你必须 P/Invoke 它。

<summary>Check password during password reset.

    The result from NetValidatePasswordReset, this member can be one of the following values.

        NERR_Success                        The password passes the validation check.
        NERR_PasswordTooShort           Validation failed. The password does not meet policy requirements because it is too short.
        NERR_PasswordTooLong                Validation failed. The password does not meet policy requirements because it is too long.
        NERR_PasswordNotComplexEnough   Validation failed. The password does not meet policy requirements because it is not complex enough.
        NERR_PasswordFilterError        Validation failed. The password does not meet the requirements of the password filter DLL.
</summary>
UInt32 TestPasswordComplexity(String username, SecureString password)
{
   //All code on stack overflow is in the public domain; no attribution
   //is required.
   const UInt32 NetValidatePasswordReset = 3;

   NET_VALIDATE_PASSWORD_RESET_INPUT_ARG args = new NET_VALIDATE_PASSWORD_RESET_INPUT_ARG();
   args.UserAccountName = Username; //some policies check that your password cannot contain your username
   args.ClearPassword = SecureStringToString(password);

   PNET_VALIDATE_OUTPUT_ARG res;

   DWORD le = NetValidatePasswordPolicy(null, null, NetValidatePasswordReset, @args, {out}Pointer(res));

   if (le <> NERR_Success)
      throw new WindowsException(le); //

   return res.ValidationStatus;
}
Run Code Online (Sandbox Code Playgroud)