“用户必须在下次登录时更改密码”时LDAPvalidation失败。 有解决方案吗

当设置“用户必须在下次登录时更改密码”时,我在用户validation时遇到问题。

以下是我validation用户的方法:

Boolean ValidateUser(String userName, String password) { try { var userOk = new DirectoryEntry("LDAP://", userName, password, AuthenticationTypes.Secure | AuthenticationTypes.ServerBind); return true; } catch (COMException ex) { if (ex.ErrorCode == -2147023570) // 0x8007052E -- Wrong user or password return false; else throw; } } 

设置“必须更改密码”时,将按预期捕获COMException,但是, ErrorCode与密码错误时相同。

有谁知道如何解决这一问题?

我需要一个返回代码,告诉密码是正确的,并且用户必须更改密码。

我不想在C#中实现Kerberos只是为了在用户必须更改密码时检查该死的标志。

经过长时间的互联网搜索,一些带有错误信息的实证工作以及通过Win32API进行的一些探索,我找到了一个迄今为止有效的解决方案。

 Boolean ValidateUser(String userName, String password) { try { var user = new DirectoryEntry("LDAP://", userName, password); var obj = user.NativeObject; return true; } catch (DirectoryServicesCOMException ex) { /* * The string " 773," was discovered empirically and it is related to the * ERROR_PASSWORD_MUST_CHANGE = 0x773 that is returned by the LogonUser API. * * However this error code is not in any value field of the * error message, therefore we need to check for the existence of * the string in the error message. */ if (ex.ExtendedErrorMessage.Contains(" 773,")) throw new UserMustChangePasswordException(); return false; } catch { throw; } } 

不幸的是,使用错误消息并不是一种非常简单的方法来validation帐户登录被拒绝的原因。 因此,了解LDAP环境如何管理用户帐户非常重要。 在Microsoft Active Directory中, userAccountControl字段用于处理大多数帐户状态。 以下是常见userAccountControl位的列表:

 LDAP_UF_ACCOUNT_DISABLE = 2 LDAP_UF_HOMEDIR_REQUIRED = 8 LDAP_UF_LOCKOUT = 16 LDAP_UF_PASSWD_NOTREQD = 32 LDAP_UF_PASSWD_CANT_CHANGE = 64 LDAP_UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED = 128 LDAP_UF_NORMAL_ACCOUNT = 512 LDAP_UF_INTERDOMAIN_TRUST_ACCOUNT = 2048 LDAP_UF_WORKSTATION_TRUST_ACCOUNT = 4096 LDAP_UF_SERVER_TRUST_ACCOUNT = 8192 LDAP_UF_DONT_EXPIRE_PASSWD = 65536 LDAP_UF_MNS_LOGON_ACCOUNT = 131072 LDAP_UF_SMARTCARD_REQUIRED = 262144 LDAP_UF_TRUSTED_FOR_DELEGATION = 524288 LDAP_UF_NOT_DELEGATED = 1048576 LDAP_UF_USE_DES_KEY_ONLY = 2097152 LDAP_UF_DONT_REQUIRE_PREAUTH = 4194304 LDAP_UF_PASSWORD_EXPIRED = 8388608 LDAP_UF_TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION = 16777216 LDAP_UF_NO_AUTH_DATA_REQUIRED = 33554432 LDAP_UF_PARTIAL_SECRETS_ACCOUNT = 67108864 

请记住,这些通常是组合在一起的。 因此,例如,如果具有普通帐户(LDAP_UF_NORMAL_ACCOUNT)的用户也被禁用(LDAP_UF_ACCOUNT_DISABLE),则LDAP字段userAccountControl将设置为514(因为512 + 2 = 514)

现在,回答原始问题:当用户帐户设置为“必须更改密码”时,AD只会将LDAP_UF_PASSWORD_EXPIRED添加到userAccountControl字段。 所以:普通帐户:LDAP_UF_NORMAL_ACCOUNT + LDAP_UF_PASSWORD_EXPIRED = 8389120

对于此特定实例(密码已过期),这是迄今为止最常见的值,但它不是唯一的值。 在评估帐户是否设置为密码已过期时,您需要考虑所有可能的选项。

当然,这不是validation设置的最简单方法,但它是最可靠的方式。

谢谢你。 这对我有用。 使用此链接我在exception发生后扩展了响应,如下所示:

 Catch ex As DirectoryServicesCOMException Dim msg As String = Nothing Select Case True Case ex.ExtendedErrorMessage.Contains("773") msg = "Error 773. User must change password at next logon is set.​ Please contact support." Case ex.ExtendedErrorMessage.Contains("525") msg = "User not found" Case ex.ExtendedErrorMessage.Contains("52e") msg = "Invalid credentials" Case ex.ExtendedErrorMessage.Contains("530") msg = "Not permitted to logon at this time​" Case ex.ExtendedErrorMessage.Contains("531") msg = "Not permitted to logon at this workstation​" Case ex.ExtendedErrorMessage.Contains("532") msg = "Password expired" Case ex.ExtendedErrorMessage.Contains("533") msg = "Account disabled" Case ex.ExtendedErrorMessage.Contains("701") msg = "Account expired" Case ex.ExtendedErrorMessage.Contains("775") msg = "User account is locked" End Select If msg IsNot Nothing Then errorLabel.Text = ex.Message & " " & msg Else errorLabel.Text = ex.Message End If End Try