Как проверить учетные данные пользователя AD, если срок действия пароля истек или «пользователь должен изменить пароль при следующем входе в систему» - PullRequest
3 голосов
/ 23 января 2012

Я хотел бы выяснить, существует ли какой-либо .Net способ проверки учетных данных пользователя Active Directory, даже если срок действия пароля истек или у пользователя установлено «пользователь должен сменить пароль при следующем входе в систему». Я пробовал PrincipalContext.ValidateCredential, и это возвращает false для моего пользователя. Я также попробовал Ldap Bind, и это тоже не работает. Моя цель состоит в том, чтобы аутентифицировать пользователя и затем предложить ему диалоговое окно смены пароля, если срок действия его пароля истек или он должен изменить пароль при следующем входе в систему.

Ответы [ 3 ]

6 голосов
/ 31 мая 2012

У нас есть несколько контроллеров AD в нашей настройке, и метод PrincipalContext.ValidateCredentials всегда будет возвращать false на контроллерах AD на серверах Windows 2003 для пользователей с установленным флажком «пользователь должен изменить пароль при следующем входе в систему».

Но на серверах под управлением Windows 2008 R2 он вернул бы true, если бы кредиты были действительны, даже если флажок был установлен.

Так что я просто убедился, что мой код попал в одну изWindows 2008 R2 серверов, и это сделало свое дело.

Я работал над решением для серверов 2003 года (прежде чем я понял, что все будет работать на других).Вот код:

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();
  }
}
0 голосов
/ 15 августа 2012

Я нашел абсолютно НЕТ СПОСОБА для проверки пользователя, если установлен флаг «Пользователь должен сменить пароль при следующем входе в систему».

Это решение, которое я придумал. Извините, это в VB, это унаследованный код:)


    ' Authenticate Using the Administrator Account
    Dim domainAndUserName As String = tmpDomain + "\" + tmpUser
    Dim entry As DirectoryEntry = New DirectoryEntry(sLDAP_PATH, m_AD_BIND_USERNAME, m_AD_BIND_PASSWORD)
    Dim ds As DirectorySearcher = New DirectorySearcher(entry)
    ds.Filter = "(&(objectClass=user)(anr=" + tmpUser + "))"

    ' Lookup the User
    Dim user As SearchResult = ds.FindOne()

    ' Check the User Status

    ' If the "User must change password at next logon" flag is set
    ' then we need to clear it before we can test the users credentials                
    If Convert.ToInt64(user.Properties("pwdLastSet").Item(0)) = 0 Then
        Dim deUser As DirectoryEntry = user.GetDirectoryEntry()
        deUser.Properties("pwdLastSet")(0) = -1
        deUser.CommitChanges()

        Dim isValidCreds As Boolean = True

        ' Create Directory Entry for User
        entry = New DirectoryEntry(sLDAP_PATH, domainAndUserName, Password)

        ' Attempt to create NativeObject based on credentials
        ' If it fails the credentials are invalid
        Try
            Dim obj As Object = entry.NativeObject()
        Catch ex As Exception
            isValidCreds = False
        End Try

        ' Reset the flag
        deUser.Properties("pwdLastSet")(0) = 0
        deUser.CommitChanges()

        ' If the credentials are valid, return '1907'
        ' if the credentials aren't valid, return '1326'
        If isValidCreds Then
            Throw New Exception("1907") ' Password Expired
        Else
            Throw New Exception("1326") ' Invalid Login
        End If
    ElseIf Convert.ToInt64(user.Properties("userAccountControl").Item(0)) = 514 Then
        Throw New Exception("1331") ' Account Disabled
    ElseIf user.Properties("lockoutTime").Count > 0 AndAlso Convert.ToInt64(user.Properties("lockouttime").Item(0)) > 0 Then
        Throw New Exception("1909") ' Account Locked Out
    End If

Единственное, о чем следует знать, это то, что существует вероятность возникновения проблемы из-за медленной репликации, т. Е. Вы можете установить флаг, но поскольку обновление не реплицировалось на все ваши контроллеры домена, когда вы пытаетесь создать NativeObject «это все еще может потерпеть неудачу.

0 голосов
/ 23 января 2012

Эта статья может помочь.Вы можете использовать DirectorySearcher, чтобы узнать, существует ли пользователь и каков статус пароля.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...