简体   繁体   English

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

[英]Determine AD password policy programmatically

I have been using the System.DirectoryService (ADSI) classes and methods to create and change users in an Active Directory.我一直在使用System.DirectoryService (ADSI) 类和方法在 Active Directory 中创建和更改用户。

Recently we added a feature to allow users to set their own password through the system.最近我们添加了一项功能,允许用户通过系统设置自己的密码。 However, using the SetPassword method throws an exception when the password is not accepted by the Password Policy set.但是,当密码策略集不接受密码时,使用SetPassword方法会引发异常。

userEntry.Invoke("SetPassword", new object[] {password});

My question is: How do I check to see if a password lives up to the password policy, before attempting to use the SetPassword-method?我的问题是:在尝试使用 SetPassword 方法之前,如何检查密码是否符合密码策略?

I read in this post that you can get the Password Policy-settings from the root domain node, but where can I read more about what each attribute means?我在这篇文章中读到,您可以从根域节点获取密码策略设置,但是我在哪里可以阅读有关每个属性含义的更多信息? For instance, which characters are required to fullfill the "Complexity" policy?例如,完成“复杂性”策略需要哪些字符?

Once I know this, I can implement my own password check-method, but as this is an error-prone approach, I would rather use a built-in check and give the user appropriate info on what is wrong with their password.一旦我知道这一点,我就可以实现我自己的密码检查方法,但由于这是一种容易出错的方法,我宁愿使用内置检查并为用户提供有关其密码错误的适当信息。

I am working on a similar project at my work. 我正在工作一个类似的项目。 We are rolling a forgot password application. 我们正在推出一个忘记密码的应用程序。 I ended up just doing an Invoke("SetPassword", "[randomString]") and saved the random string for the Invoke("ChangePassword","[randomString]","[user supplied pw]") . 我最后只是做一个Invoke("SetPassword", "[randomString]")并保存了Invoke("ChangePassword","[randomString]","[user supplied pw]")的随机字符串。 The result of the ChangePassword was returned to the user. ChangePassword的结果已返回给用户。

SetPassword does not check for password complexity or history rules. SetPassword不检查密码的复杂性或历史记录规则。 It is the same as right clicking a user in AD and selecting "Reset Password." 与在AD中右键单击用户并选择“重置密码”相同。 ChangePassword however, does check for password history requirements. 但是, ChangePassword会检查密码历史记录要求。

The complexity policy is that it must contain three out of five of these types: 复杂度策略是它必须包含以下五种类型中的三种:

  • Upper case letters 大写字母
  • Lower case letters 小写字母
  • Digits 位数
  • Non-alphanumeric characters: ~!@#$%^&*_-+=`|(){}[]:;"'<>,.?/ 非字母数字字符:〜!@#$%^&* _- + =`|(){} [] :;“'<>,。?/
  • Unicode characters that are alphabetics but not uppercase or lowercase. Unicode字符为字母,但不是大写或小写。

It also can't be the sAMAccountName or displayName (or parts of). 也不能是sAMAccountName或displayName(或部分)。 You can read about it here . 你可以在这里阅读。 The other password policy rules are in adjacent documents . 其他密码策略规则在相邻文档中

You could try setting it and catch exceptions but from memory I don't think it tells you what's wrong with the password, just that it doesn't meet the requirements. 您可以尝试设置它并捕获异常,但是从内存来看,我认为它不能告诉您密码有什么问题,只是密码不符合要求。

The API function you want is NetValidatePasswordPolicy .您想要的 API 函数是NetValidatePasswordPolicy

There are three modes it operates in:它在三种模式下运行:

  • NetValidateAuthentication : if you are authenticating a user; NetValidateAuthentication :如果您正在对用户进行身份验证; so the function can check password expiration policies, bad login attempts, account lockouts, bad login attempts, etc因此该功能可以检查密码过期策略、错误登录尝试、帐户锁定、错误登录尝试等
  • NetValidatePasswordChange : if the user is changing their password; NetValidatePasswordChange :如果用户正在更改他们的密码; so the function can check against lockout, or against the password policy因此该函数可以检查锁定或密码策略

and the mode you want:和你想要的模式:

  • NetValidatePasswordReset : you are an admin resetting a user's password; NetValidatePasswordReset :您是重置用户密码的管理员; which only checks the password complexity.它只检查密码的复杂性。

I'll try transcoding from another language to C# on the fly;我将尝试从另一种语言即时转码为 C#; but you will have to P/Invoke it.但你将不得不 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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM