Active Directory - проверьте имя пользователя / пароль - PullRequest
35 голосов
/ 30 декабря 2008

Я использую следующий код в Windows Vista Ultimate SP1 для запроса нашего активного сервера каталогов, чтобы проверить имя пользователя и пароль пользователя в домене.

public Object IsAuthenticated()
{
    String domainAndUsername = strDomain + "\\" + strUser;
    DirectoryEntry entry = new DirectoryEntry(_path, domainAndUsername, strPass);
    SearchResult result;
    try
    {
        //Bind to the native AdsObject to force authentication.         

        DirectorySearcher search = new DirectorySearcher(entry) { Filter = ("(SAMAccountName=" + strUser + ")") };

        search.PropertiesToLoad.Add("givenName"); // First Name                
        search.PropertiesToLoad.Add("sn"); // Last Name
        search.PropertiesToLoad.Add("cn"); // Last Name

        result = search.FindOne();

        if (null == result)
        {
            return null;
        }

        //Update the new path to the user in the directory.
        _path = result.Path;
        _filterAttribute = (String)result.Properties["cn"][0];
    }
    catch (Exception ex)
    {
        return new Exception("Error authenticating user. " + ex.Message);
    }
    return user;
}

цель использует .NET 3.5 и скомпилирована со стандартом VS 2008

Я вошел в систему под учетной записью домена, которая является администратором домена, на котором запущено приложение.

Код отлично работает на Windows XP; но я получаю следующее исключение при запуске его в Vista:

System.DirectoryServices.DirectoryServicesCOMException (0x8007052E): Logon failure: unknown user name or bad password.

   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
   at System.DirectoryServices.DirectorySearcher.FindOne()
   at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated()
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectorySearcher.FindAll(Boolean findMoreThanOne)
   at System.DirectoryServices.DirectorySearcher.FindOne()
   at Chain_Of_Custody.Classes.Authentication.LdapAuthentication.IsAuthenticated()

Я пытался изменить типы аутентификации, я не уверен, что происходит.


См. Также : Проверить имя пользователя и пароль в Active Directory?

Ответы [ 4 ]

50 голосов
/ 01 января 2009

Если вы используете .net 3.5, используйте этот код.

Для аутентификации пользователя:

PrincipalContext adContext = new PrincipalContext(ContextType.Domain);

using (adContext)
{
     return adContext.ValidateCredentials(UserName, Password);
}

Если вам нужно найти пользователя для R / W атрибутов объекта, сделайте это:

PrincipalContext context = new PrincipalContext(ContextType.Domain);
UserPrincipal foundUser = 
    UserPrincipal.FindByIdentity(context, "jdoe");

Это использует пространство имен System.DirectoryServices.AccountManagement, поэтому вам необходимо добавить его в свои операторы using.

Если вам нужно преобразовать объект UserPrincipal в объект DirectoryEntry для работы с устаревшим кодом, вы можете сделать это:

DirectoryEntry userDE = (DirectoryEntry)foundUser.GetUnderlyingObject();
8 голосов
/ 26 марта 2010

Я обнаружил, что один и тот же код распространяется по Интернету на нескольких сайтах, и он не работает для меня. Стив Эванс, вероятно, прав, что если вы используете .NET 3.5, вам не следует использовать этот код. Но если вы все еще используете .NET 2.0, вы можете попробовать это для аутентификации в ваших службах AD:

DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain, 
   userName, password, 
   AuthenticationTypes.Secure | AuthenticationTypes.SecureSocketsLayer);
object nativeObject = entry.NativeObject;

Первая строка создает объект DirectoryEntry с использованием домена, имени пользователя и пароля. Он также устанавливает AuthenticationTypes. Обратите внимание, как я устанавливаю безопасную (Kerberos) аутентификацию и SSL, используя оператор «Bitwise OR» ('|') между двумя параметрами.

Вторая строка заставляет NativeObject «entry» связываться со службами AD, используя информацию из первой строки.

Если выдается исключение, то учетные данные (или настройки) были неверными. Если не исключение, вы аутентифицированы. Сообщение об исключении обычно указывает, что пошло не так.

Этот код очень похож на тот, который у вас уже есть, но домен используется там, где у вас есть «путь», а имя пользователя не объединяется с доменом. Убедитесь, что вы правильно установили AuthenticationTypes. Это может сделать или сломать возможность аутентификации.

1 голос
/ 31 декабря 2008

Я все равно понял, что если вы перейдете в домен с именем пользователя на Vista, он не будет работать как "домен \ пользователь", поэтому просто передать "пользователь" вместо этого, кажется, все в порядке - за исключением того, что вы должны быть в том же домене

0 голосов
/ 30 декабря 2008

Требуется ли привязка к LDAP с повышенными привилегиями (UAC)? Вы можете попробовать запустить Visual Studio и / или приложение в качестве администратора и посмотреть, поможет ли это. Если это проблема, вы всегда можете добавить манифест в приложение и установить для него требование повышения прав, таким образом он будет запрашивать, когда пользователь запускает его.

Не уверен, почему это потребует повышенных привилегий, но оно того стоит.

...