且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在用户密码过期或“用户下次登录时必须更改密码"时检查 AD 用户凭据

更新时间:2021-07-28 08:53:49

我们的设置中有多个 AD 控制器,并且 PrincipalContext.ValidateCredentials 方法将始终在 Windows 2003 服务器上的 AD 控制器上返回 false下次登录时更改密码"复选框已选中.

We have several AD controllers in our setup and the PrincipalContext.ValidateCredentials method would always return false on the AD controllers on Windows 2003 servers on users with the "user must change password at next logon" checkbox checked.

但是在 Windows 2008 R2 服务器上,即使选中了复选框,如果凭据有效,它也会返回 true.

But on the ones on Windows 2008 R2 servers, it would return true if the creds were valid even if the checkbox was checked.

所以我只是确保我的代码运行在一台 Windows 2008 R2 服务器上,这就成功了.

So I just made sure my code was hitting one of the windows 2008 R2 servers and that did the trick.

我确实为 2003 服务器开发了一个解决方案(在我意识到事情只能在其他服务器上工作之前).代码如下:

I did work on a solution for the 2003 servers (before I realized things would just work on the other ones). Here is the code:

var adContext = new PrincipalContext(ContextType.Domain, adLocation, adContainer, adAdminUsername, adAdminPassword);

var initialValidation = adContext.ValidateCredentials(username, password);
Console.WriteLine("Initial validation returned: " + initialValidation);

if (!initialValidation)
{
    // maybe validation failed because "user must change password at next logon".
    // let's see if that is the case.

    var user = UserPrincipal.FindByIdentity(adContext, username);
    if (user.LastPasswordSet == null)
    {
        // the user must change his password at next logon. So this might be
        // why validation returned false

        // uncheck the "change password" checkbox and attempt validation again

        var deUser = user.GetUnderlyingObject() as DirectoryEntry;
        var property = deUser.Properties["pwdLastSet"];
        property.Value = -1;
        deUser.CommitChanges();

        // property was unset, retry validation
        adContext.ValidateCredentials(username, password);
        Console.WriteLine("Secondary validation returned: " + adContext.ValidateCredentials(username, password));

        // re check the checkbox
        property.Value = 0;
        deUser.CommitChanges();
  }
}