System.DirectoryServices - сервер не работает - PullRequest
15 голосов
/ 28 октября 2011

Я получаю сообщение об ошибке на веб-сайте, на котором я использую аутентификацию Windows.

Странные вещи:

  • Происходит только в том случае, если пользователь еще не сохранен в базе данных (новый неизвестный пользователь)
  • Появляется только в действующей системе, все нормально в локальной среде разработки

Вот что я получаю в журнале регистрации:

Источник: Система.DirectoryServices

Сообщение: сервер не работает.

Трассировка:
в System.DirectoryServices.DirectoryEntry.Bind (Boolean throwIfFail)
в System.DirectoryServices.DirectoryEntry.Bind()
в System.DirectoryServices.DirectoryEntry.get_AdsObject ()
в System.DirectoryServices.DirectorySearcher.FindAll (логический findMoreThanOne)
в System.DirectoryServices.DirectorySearcher.FindOne () * 1023.DataAccess.UserListManager.SaveUser (String windowsUserName)

Вот как я реализую DirectorySearch:

private void SaveUser(string windowsUserName)
{
    string[] domainAndUser = windowsUserName.Split('\\');
    string domain = domainAndUser[0];
    string username = domainAndUser[1];

    DirectoryEntry entry = new DirectoryEntry("LDAP://" + domain);
    DirectorySearcher search = new DirectorySearcher(entry);

    try
    {
        // Bind to the native AdsObject to force authentication.
        search.Filter = "(SAMAccountName=" + username + ")";
        search.PropertiesToLoad.Add("cn");
        search.PropertiesToLoad.Add("sn");
        search.PropertiesToLoad.Add("givenName");
        search.PropertiesToLoad.Add("mail");

        SearchResult result = search.FindOne();

        if (result == null)
        {
            throw new Exception("No results found in Windows authentication.");
        }

        User userToSave = new User();
        userToSave.FirstName = (String) result.Properties["givenName"][0];
        userToSave.LastName = (String) result.Properties["sn"][0];
        userToSave.Email = (String) result.Properties["mail"][0];
        userToSave.Username = windowsUserName;
        userToSave.Guid = Guid.NewGuid();

        SaveUser(userToSave);
    }
    catch (Exception ex)
    {
        throw new Exception("Error authenticating user. " + ex.Message, ex);
    }
    finally
    {
        //Dispose service and search to prevent leek in memory
        entry.Dispose();
        search.Dispose();
    }
}

Если нужно больше примеров кодаЭд просто скажи мне.

Ответы [ 4 ]

20 голосов
/ 28 октября 2011

Ваша проблема в том, что вы используете «простое» имя домена для привязки - это не будет работать в LDAP.На самом деле, если вы пытаетесь привязаться к LDAP://MyDomain, то, что вы действительно делаете, пытается привязаться к серверу с именем MyDomain.

Вам нужна правильная строка привязки LDAP - что-то вроде LDAP://dc=yourdomain,dc=local или что-то в этом роде.

Чтобы узнать, какой у вас контекст привязки LDAP по умолчанию, используйте этот фрагмент кода:

DirectoryEntry deRoot = new DirectoryEntry("LDAP://RootDSE");

if (deRoot != null)
{
   string defaultNamingContext = deRoot.Properties["defaultNamingContext"].Value.ToString();
}

Как только вы получите эту строку - используйте ее в качестве строки привязки к вашему серверу LDAP.

А если вы используете .NET 3.5 и выше, вам следует проверить System.DirectoryServices.AccountManagement (S.DS.AM) пространство имен.Прочитайте все об этом здесь:

По сути, вы можете определить контекст домена и легко находить пользователей и / или группы в AD:

// set up domain context -- no domain name needed, uses default domain 
PrincipalContext ctx = new PrincipalContext(ContextType.Domain);

// find a user
UserPrincipal user = UserPrincipal.FindByIdentity(ctx, username);

if(user != null)
{
   // do something here....     
}

Новый S.DS.AM позволяет действительно легкопоиграйтесь с пользователями и группами в AD!

1 голос
/ 04 августа 2015

Чтобы добавить к marc_s ответ выше , мне нужно было выполнить поиск по нескольким доменам.Поэтому для каждого домена я сделал следующее:

DirectoryEntry deRoot = new DirectoryEntry("LDAP://" +"DomainName"+ "/RootDSE");
string defaultNamingContext = "LDAP://" + deRoot.Properties["defaultNamingContext"].Value.ToString();
DirectoryEntry mySearchRoot = new DirectoryEntry(defaultNamingContext);
DirectorySearcher myDirectorySearcher = new DirectorySearcher(mySearchRoot);
0 голосов
/ 29 мая 2017

Подобная ошибка произошла со мной (хотя это происходило все время, а не в определенных случаях, как указано здесь) из-за неправильной строки подключения Active Directory. Я использовал Corp вместо Prod. Используйте то, что работает для другого приложения в вашей организации, если оно существует.

0 голосов
/ 06 января 2017

Вы можете использовать строки связывания в формате LDAP: //mydomain.com: 389.Я продолжал получать «Доступ запрещен» при попытке использовать формат LDAP: // DC = mydomain, DC = com.Как только я переключился на формат LDAP: //mydomain.com: 389 и связал его с использованием флага AuthenticationTypes.ServerBind при создании моего DirectoryEntry, все заработало отлично.Это было в службе приложений Azure.

...