Вопрос

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

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?

Это было полезно?

Решение

Если вы используете .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");

Это использование Системы.ДиректориЙсервисы.Пространство имен AccountManagement, поэтому вам нужно будет добавить его в свои инструкции using.

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

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

Другие советы

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

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

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

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

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

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

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

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

Не уверен, зачем для этого нужны повышенные привилегии, но попробовать стоит.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top