Подтвердить что ты не робот

Active Directory - проверить имя пользователя/пароль

Я использую следующий код в 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.

4b9b3361

Ответ 1

Если вы используете .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, поэтому вам нужно добавить его в свои операторы.

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

DirectoryEntry userDE = (DirectoryEntry)foundUser.GetUnderlyingObject();

Ответ 2

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

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

Первая строка создает объект DirectoryEntry, используя домен, имя пользователя и пароль. Он также устанавливает типы аутентификации. Обратите внимание, как я устанавливаю аутентификацию Secure (Kerberos) и SSL, используя оператор "Побитовое ИЛИ" ('|') между двумя параметрами.

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

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

Этот код очень похож на то, что у вас уже есть, но домен используется там, где у вас есть "путь", а имя пользователя не объединено с доменом. Не забудьте также правильно установить свои типы аутентификации. Это может сделать или нарушить возможность аутентификации.

Ответ 3

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

Ответ 4

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

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