6

在 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

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

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

密码重置工作正常,用户可以使用他们的新密码登录,但他们的旧密码不应该仍然有效。

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

有人见过这样的吗?

4

5 回答 5

5

这个问题与代码无关,但听到的罪魁祸首是活动目录......

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

于 2012-02-06T10:33:22.437 回答
1

我在这里找到了答案

从链接...

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

于 2009-04-16T22:13:41.947 回答
1

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

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

谢谢Ch

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

历史:

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

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

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

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

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

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

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

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

于 2011-07-01T17:59:19.130 回答
0

您是否考虑到 AD 需要在整个网络中传播此类更改所需的长达 15 分钟的时间?

马克

于 2009-04-16T15:43:37.143 回答
0

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

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

于 2009-04-16T15:45:55.967 回答