DirectoryServices.AccountManagement“旧”密码在密码更改后仍然有效

时间:2022-09-28 02:59:01

After resetting a users password in Active Directory, if the user tries to log in using their old password, the following code validates as True:

在Active Directory中重置用户密码后,如果用户尝试使用旧密码登录,则以下代码验证为True:

Dim up As UserPrincipal = GetAdUser(objContext, arg_strBA, arg_strUsername)

If up IsNot Nothing Then

    Dim valid As Boolean = up.Context.ValidateCredentials(
    up.UserPrincipalName, arg_strPassword, ContextOptions.Negotiate)


    If (valid) Then strReturn = up.SamAccountName

End If

We are resetting the password using the following code:

我们正在使用以下代码重置密码:

Dim objUser As New DirectoryEntry(arg_strLDAPPath)

If Not objUser Is Nothing Then
    objUser.AuthenticationType = AuthenticationTypes.Secure


    objUser.Invoke("SetPassword", arg_strNewPW)
    objUser.CommitChanges()
end if

The password reset works fine and the user can log in with their new password, but their old password should not still validate.

密码重置工作正常,用户可以使用新密码登录,但旧密码仍不能验证。

When the above ValidateCredentials works for the old password, we are assigning the credentials to a web service call, which then fails with a "401: Unauthorized" error.

当上述ValidateCredentials适用于旧密码时,我们将凭据分配给Web服务调用,然后失败并显示“401:Unauthorized”错误。

Anyone seen anything like this?

有人见过这样的事吗?

Thanks Dirk

5 个解决方案

#1


This issue is not related to Code but the culprit over hear is the Active directory...

这个问题与Code无关,但是听到的罪魁祸首是Active目录......

Please refer http://support.microsoft.com/kb/906305 for solution...

请参考http://support.microsoft.com/kb/906305获取解决方案......

#2


This Works - See SOLUTION below - Please let me know if you find this helpful as our shop is divided on whether this is an OK solution.

这项工作 - 请参阅下面的解决方案 - 如果您觉得这有用,请告诉我们,因为我们的商店对这是否是一个好的解决方案存在分歧。

The following is a Solution to Active Directory Allowing Old Password to work after being changed. I would very much like feedback on the acceptance of this solution as it uses the ChangePassword during the Login Authentication. This is an odd thing to do but it works. Currently our shop is not using this solution so if anyone can tell me if they are using it or not that would be appreciated.

以下是Active Directory允许旧密码在更改后工作的解决方案。我非常希望得到关于接受此解决方案的反馈,因为它在登录身份验证期间使用ChangePassword。这是一个奇怪的事情,但它的工作原理。目前我们的商店没有使用此解决方案,所以如果有人能告诉我他们是否正在使用它,那将是值得赞赏的。

Thank you Ch

谢谢Ch

Active Directory and Old Passwords returning Valid (15 minutes to +- hour). This occurs when SetPassword or ChangePassword are Invoked.

返回的Active Directory和旧密码有效(15分钟到+ - 小时)。调用SetPassword或ChangePassword时会发生这种情况。

History:

I find that this is called a “Feature” of AD and is by design built into AD so that when a user changes passwords there is a kind of grace period that allows all resources using those passwords to transfer over to the new one.

我发现这被称为AD的“功能”,并且是设计在AD中的设计,因此当用户更改密码时,存在一种宽限期,允许使用这些密码的所有资源转移到新密码。

One example of AD that supports the concept that AD knows the latest password is that of changing a login password on a PC – in this case the computer will not allow the old password to login. While I do not have the answer to this (other than Microsoft had to get this to work) it is my opinion that this is not as simple as it may appear as the PC is involved and it has passwords on it too.

支持AD知道最新密码概念的AD的一个示例是更改PC上的登录密码 - 在这种情况下,计算机将不允许旧密码登录。虽然我没有这方面的答案(除了微软必须让它工作),我认为这并不像PC所涉及的那样简单,它也有密码。

One example showing how password changes in AD do last for a time period may be:

显示AD​​中密码更改如何持续一段时间的一个示例可能是:

Using Remote Desktop from a Windows 7 PC to a Windows Server 2008 R2 box. Login from the Windows Security Box then the , click OK box appears, click OK and you are logged in. Now Change your password for the user you used to Remote into the box with (different from your Kirkman user ??), logout and login again with old password (within timeframe 15 minutes to an hour +-). The old password will get you past the Windows Security box and to the OK Box. When you click OK it will then fail. If you start over from Remote Desktop and try a bad password you will be stopped at the Windows Security Box with message “The Logon attempt failed”. After the time limit expires you will not get past the Windows Security box with the old password. (make sure to start from Remote Desktop each time NOT switch users which will act as expected which also shows that the PC in involved somehow). At least it does not the user login – but this does show that (what appears to be AD) at some level allows old passwords to authenticate to some level.

使用从Windows 7 PC到Windows Server 2008 R2的远程桌面。从Windows安全框登录然后出现,单击确定框,单击确定,然后您已登录。现在将您用于远程用户的密码更改为(与您的Kirkman用户不同??),注销和登录再次使用旧密码(在15分钟到一小时的时间范围内+ - )。旧密码将通过Windows安全框和OK框。单击“确定”后,它将失败。如果从远程桌面重新开始并尝试输入错误密码,则会在Windows安全框中停止显示“登录尝试失败”消息。时间限制到期后,您将无法使用旧密码通过Windows安全框。 (确保每次不切换用户的远程桌面,这将按预期运行,这也表明涉及PC的某种方式)。至少它不是用户登录 - 但这确实表明(某些级别似乎是AD)允许旧密码在某种程度上进行身份验证。

Research: I have found many references to this problem and only one potential solution that to this point I have not been able to determine if we can implement it (this is the reference to calling strictly via Kerberos and not NTLM which is not as simple as it may appear according to the documentation and my research). I have found many links to how to interact with AD in .NET but no actual AD Manual.

研究:我发现了很多关于这个问题的引用,并且只有一个可能的解决方案到目前为止我还无法确定我们是否可以实现它(这是严格通过Kerberos而不是NTLM调用的引用,这并不像它可能会出现在文件和我的研究中)。我找到了很多关于如何在.NET中与AD交互的链接,但没有实际的AD手册。

SOLUTION SOLUTION SOLUTION - Read this part if you want the SOlution SOLUTION!!! Present: I have found (by accident during testing) that the ChangePassword call to AD will not allow the OldPassword passed to it succeed in changing the password to the new password. It is my opinion that this test that does work is not actually known as I have not found any reference to it being used. I actually have not found any solution to this problem. One morning at 3:00 am I realized that I could exploit this use of ChangePassword to provide a solution to this problem – at least a work-around we can use immediately until we can determine a better approach.

解决方案解决方案 - 如果您需要SOlution解决方案,请阅读此部分!现在:我发现(在测试期间偶然)对AD的ChangePassword调用不允许传递给它的OldPassword成功将密码更改为新密码。我认为这个有效的测试实际上并不知道,因为我没有找到任何使用它的参考。我实际上还没有找到解决这个问题的方法。一天早上凌晨3点,我意识到我可以利用ChangePassword的这种方法来解决这个问题 - 至少我们可以立即使用解决方案,直到我们能够确定更好的方法。

First I check that everything is valid and AD returns that the password is valid. Then a call to ChangePassword (username, oldpassword, newpassword) with the oldpassword and newpassword as password provided by the user (both the same) is done. I know one of two (possibly three but the password policy violation stops it from succeeding) outcomes will happen. Either the OldPassword is good and we fail because the Password Policy is not met (history, new password cannot be one of last N passwords) or we fail because the Old Password is incorrect (both returned as Exception error with text in message). We check for this last condition and if the oldpassword is not valid we do not let the user log in.

首先,我检查一切是否有效,AD返回密码有效。然后使用oldpassword和newpassword作为用户提供的密码(两者都相同)调用ChangePassword(用户名,oldpassword,newpassword)。我知道其中一个(可能是三个,但密码策略违规阻止它成功)结果将会发生。 OldPassword是好的,我们失败,因为密码策略不符合(历史记录,新密码不能是最后N个密码之一)或我们失败,因为旧密码不正确(两者都作为异常错误返回消息中的文本)。我们检查最后一个条件,如果oldpassword无效,我们不允许用户登录。

Future: Maybe a second set of eyes will help.
I think the solution is in Impersonation or Kerberos. I have not had success in finding out enough on either of these as solutions. It is obvious that AD can differentiate between old passwords because the ChangePassword does it. What we are doing is at the heart of security so not everything is open (like the ability to see password history in AD, I have not found a way to access it).

未来:也许第二组眼睛会有所帮助。我认为解决方案是模拟或Kerberos。我没有成功地找到足够的解决方案。很明显,AD可以区分旧密码,因为ChangePassword会这样做。我们正在做的是安全的核心所以不是所有东西都是开放的(比如在AD中查看密码历史的能力,我还没有找到访问它的方法)。

#3


I fount the answer Here

我在这里得到答案

From the link...

从链接...

"However, what counts is that ContextOption does not ensure the use of Kerberos only. It turns out that under certain situations (like if you are specifying AD rather than local, and you have a sufficiently up to date server), the code chooses to do Negotiate no matter what. In that sense, specifying Sealing probably means that it will use Kerberos, but not necessarily exclusively. The flag that really matters is burried several layers under that. Under the covers, this method ends up establishing an LdapConnection, setting the network Credentials for the connection, setting that AuthType (the actual flag that matters!), and finally calling the Bind() method. The LdapConnection.Bind() method establishes an authenticated connection to one of the AD servers using the specified credentials. The problem is that when PrincipalContext.ValidateCredentials sets up this call (in your scenario), it always sets the AuthType = Negotiate. In this case, Kerberos does in fact get used, and ends up failing, but the system falls back to NTLM."

“但是,重要的是ContextOption不能确保仅使用Kerberos。事实证明,在某些情况下(如果您指定AD而不是本地,并且您有足够的最新服务器),代码选择无论如何都要进行协商。从这个意义上说,指定Sealing可能意味着它将使用Kerberos,但不一定是唯一的。真正重要的标志在其下面埋了几层。在封面下,这个方法最终建立了一个LdapConnection,设置连接的网络凭据,设置AuthType(重要的实际标志!),最后调用Bind()方法.LdapConnection.Bind()方法使用指定的凭据建立与其中一个AD服务器的经过身份验证的连接。问题是,当PrincipalContext.ValidateCredentials设置此调用时(在您的场景中),它总是设置AuthType = Negotiate。在这种情况下,Kerberos确实会被使用,并最终成为fa iling,但系统回归到NTLM。“

#4


Did you take the up to 15 minutes of time into account that AD requires to propagate changes like that throughout the network??

您是否考虑过AD需要在整个网络中传播类似的更改?

Marc

#5


I assume you're ValidateCredentials executes on a client machine. If that is the case, then it has the old (successful) password cached. This is done to enable users to login if the Active Directory is offline or unreachable. Propagating changes takes some time.

我假设您在客户端计算机上执行ValidateCredentials。如果是这种情况,那么它会缓存旧的(成功的)密码。这样做是为了使用户能够在Active Directory脱机或无法访问时登录。传播变化需要一些时间。

If you want to get around this, you should authenticate with the Server serving the Webservice at authentication time instead of the local client machine.

如果您想解决此问题,则应在身份验证时使用服务于Web服务的服务器而不是本地客户端计算机进行身份验证。

#1


This issue is not related to Code but the culprit over hear is the Active directory...

这个问题与Code无关,但是听到的罪魁祸首是Active目录......

Please refer http://support.microsoft.com/kb/906305 for solution...

请参考http://support.microsoft.com/kb/906305获取解决方案......

#2


This Works - See SOLUTION below - Please let me know if you find this helpful as our shop is divided on whether this is an OK solution.

这项工作 - 请参阅下面的解决方案 - 如果您觉得这有用,请告诉我们,因为我们的商店对这是否是一个好的解决方案存在分歧。

The following is a Solution to Active Directory Allowing Old Password to work after being changed. I would very much like feedback on the acceptance of this solution as it uses the ChangePassword during the Login Authentication. This is an odd thing to do but it works. Currently our shop is not using this solution so if anyone can tell me if they are using it or not that would be appreciated.

以下是Active Directory允许旧密码在更改后工作的解决方案。我非常希望得到关于接受此解决方案的反馈,因为它在登录身份验证期间使用ChangePassword。这是一个奇怪的事情,但它的工作原理。目前我们的商店没有使用此解决方案,所以如果有人能告诉我他们是否正在使用它,那将是值得赞赏的。

Thank you Ch

谢谢Ch

Active Directory and Old Passwords returning Valid (15 minutes to +- hour). This occurs when SetPassword or ChangePassword are Invoked.

返回的Active Directory和旧密码有效(15分钟到+ - 小时)。调用SetPassword或ChangePassword时会发生这种情况。

History:

I find that this is called a “Feature” of AD and is by design built into AD so that when a user changes passwords there is a kind of grace period that allows all resources using those passwords to transfer over to the new one.

我发现这被称为AD的“功能”,并且是设计在AD中的设计,因此当用户更改密码时,存在一种宽限期,允许使用这些密码的所有资源转移到新密码。

One example of AD that supports the concept that AD knows the latest password is that of changing a login password on a PC – in this case the computer will not allow the old password to login. While I do not have the answer to this (other than Microsoft had to get this to work) it is my opinion that this is not as simple as it may appear as the PC is involved and it has passwords on it too.

支持AD知道最新密码概念的AD的一个示例是更改PC上的登录密码 - 在这种情况下,计算机将不允许旧密码登录。虽然我没有这方面的答案(除了微软必须让它工作),我认为这并不像PC所涉及的那样简单,它也有密码。

One example showing how password changes in AD do last for a time period may be:

显示AD​​中密码更改如何持续一段时间的一个示例可能是:

Using Remote Desktop from a Windows 7 PC to a Windows Server 2008 R2 box. Login from the Windows Security Box then the , click OK box appears, click OK and you are logged in. Now Change your password for the user you used to Remote into the box with (different from your Kirkman user ??), logout and login again with old password (within timeframe 15 minutes to an hour +-). The old password will get you past the Windows Security box and to the OK Box. When you click OK it will then fail. If you start over from Remote Desktop and try a bad password you will be stopped at the Windows Security Box with message “The Logon attempt failed”. After the time limit expires you will not get past the Windows Security box with the old password. (make sure to start from Remote Desktop each time NOT switch users which will act as expected which also shows that the PC in involved somehow). At least it does not the user login – but this does show that (what appears to be AD) at some level allows old passwords to authenticate to some level.

使用从Windows 7 PC到Windows Server 2008 R2的远程桌面。从Windows安全框登录然后出现,单击确定框,单击确定,然后您已登录。现在将您用于远程用户的密码更改为(与您的Kirkman用户不同??),注销和登录再次使用旧密码(在15分钟到一小时的时间范围内+ - )。旧密码将通过Windows安全框和OK框。单击“确定”后,它将失败。如果从远程桌面重新开始并尝试输入错误密码,则会在Windows安全框中停止显示“登录尝试失败”消息。时间限制到期后,您将无法使用旧密码通过Windows安全框。 (确保每次不切换用户的远程桌面,这将按预期运行,这也表明涉及PC的某种方式)。至少它不是用户登录 - 但这确实表明(某些级别似乎是AD)允许旧密码在某种程度上进行身份验证。

Research: I have found many references to this problem and only one potential solution that to this point I have not been able to determine if we can implement it (this is the reference to calling strictly via Kerberos and not NTLM which is not as simple as it may appear according to the documentation and my research). I have found many links to how to interact with AD in .NET but no actual AD Manual.

研究:我发现了很多关于这个问题的引用,并且只有一个可能的解决方案到目前为止我还无法确定我们是否可以实现它(这是严格通过Kerberos而不是NTLM调用的引用,这并不像它可能会出现在文件和我的研究中)。我找到了很多关于如何在.NET中与AD交互的链接,但没有实际的AD手册。

SOLUTION SOLUTION SOLUTION - Read this part if you want the SOlution SOLUTION!!! Present: I have found (by accident during testing) that the ChangePassword call to AD will not allow the OldPassword passed to it succeed in changing the password to the new password. It is my opinion that this test that does work is not actually known as I have not found any reference to it being used. I actually have not found any solution to this problem. One morning at 3:00 am I realized that I could exploit this use of ChangePassword to provide a solution to this problem – at least a work-around we can use immediately until we can determine a better approach.

解决方案解决方案 - 如果您需要SOlution解决方案,请阅读此部分!现在:我发现(在测试期间偶然)对AD的ChangePassword调用不允许传递给它的OldPassword成功将密码更改为新密码。我认为这个有效的测试实际上并不知道,因为我没有找到任何使用它的参考。我实际上还没有找到解决这个问题的方法。一天早上凌晨3点,我意识到我可以利用ChangePassword的这种方法来解决这个问题 - 至少我们可以立即使用解决方案,直到我们能够确定更好的方法。

First I check that everything is valid and AD returns that the password is valid. Then a call to ChangePassword (username, oldpassword, newpassword) with the oldpassword and newpassword as password provided by the user (both the same) is done. I know one of two (possibly three but the password policy violation stops it from succeeding) outcomes will happen. Either the OldPassword is good and we fail because the Password Policy is not met (history, new password cannot be one of last N passwords) or we fail because the Old Password is incorrect (both returned as Exception error with text in message). We check for this last condition and if the oldpassword is not valid we do not let the user log in.

首先,我检查一切是否有效,AD返回密码有效。然后使用oldpassword和newpassword作为用户提供的密码(两者都相同)调用ChangePassword(用户名,oldpassword,newpassword)。我知道其中一个(可能是三个,但密码策略违规阻止它成功)结果将会发生。 OldPassword是好的,我们失败,因为密码策略不符合(历史记录,新密码不能是最后N个密码之一)或我们失败,因为旧密码不正确(两者都作为异常错误返回消息中的文本)。我们检查最后一个条件,如果oldpassword无效,我们不允许用户登录。

Future: Maybe a second set of eyes will help.
I think the solution is in Impersonation or Kerberos. I have not had success in finding out enough on either of these as solutions. It is obvious that AD can differentiate between old passwords because the ChangePassword does it. What we are doing is at the heart of security so not everything is open (like the ability to see password history in AD, I have not found a way to access it).

未来:也许第二组眼睛会有所帮助。我认为解决方案是模拟或Kerberos。我没有成功地找到足够的解决方案。很明显,AD可以区分旧密码,因为ChangePassword会这样做。我们正在做的是安全的核心所以不是所有东西都是开放的(比如在AD中查看密码历史的能力,我还没有找到访问它的方法)。

#3


I fount the answer Here

我在这里得到答案

From the link...

从链接...

"However, what counts is that ContextOption does not ensure the use of Kerberos only. It turns out that under certain situations (like if you are specifying AD rather than local, and you have a sufficiently up to date server), the code chooses to do Negotiate no matter what. In that sense, specifying Sealing probably means that it will use Kerberos, but not necessarily exclusively. The flag that really matters is burried several layers under that. Under the covers, this method ends up establishing an LdapConnection, setting the network Credentials for the connection, setting that AuthType (the actual flag that matters!), and finally calling the Bind() method. The LdapConnection.Bind() method establishes an authenticated connection to one of the AD servers using the specified credentials. The problem is that when PrincipalContext.ValidateCredentials sets up this call (in your scenario), it always sets the AuthType = Negotiate. In this case, Kerberos does in fact get used, and ends up failing, but the system falls back to NTLM."

“但是,重要的是ContextOption不能确保仅使用Kerberos。事实证明,在某些情况下(如果您指定AD而不是本地,并且您有足够的最新服务器),代码选择无论如何都要进行协商。从这个意义上说,指定Sealing可能意味着它将使用Kerberos,但不一定是唯一的。真正重要的标志在其下面埋了几层。在封面下,这个方法最终建立了一个LdapConnection,设置连接的网络凭据,设置AuthType(重要的实际标志!),最后调用Bind()方法.LdapConnection.Bind()方法使用指定的凭据建立与其中一个AD服务器的经过身份验证的连接。问题是,当PrincipalContext.ValidateCredentials设置此调用时(在您的场景中),它总是设置AuthType = Negotiate。在这种情况下,Kerberos确实会被使用,并最终成为fa iling,但系统回归到NTLM。“

#4


Did you take the up to 15 minutes of time into account that AD requires to propagate changes like that throughout the network??

您是否考虑过AD需要在整个网络中传播类似的更改?

Marc

#5


I assume you're ValidateCredentials executes on a client machine. If that is the case, then it has the old (successful) password cached. This is done to enable users to login if the Active Directory is offline or unreachable. Propagating changes takes some time.

我假设您在客户端计算机上执行ValidateCredentials。如果是这种情况,那么它会缓存旧的(成功的)密码。这样做是为了使用户能够在Active Directory脱机或无法访问时登录。传播变化需要一些时间。

If you want to get around this, you should authenticate with the Server serving the Webservice at authentication time instead of the local client machine.

如果您想解决此问题,则应在身份验证时使用服务于Web服务的服务器而不是本地客户端计算机进行身份验证。