Запрос Ldap возвращает только 1000 пользователей… да, я использую подкачку

#active-directory

#active-directory

Вопрос:

У меня есть простая функция GetStaff, которая должна извлекать всех пользователей из Active Directory. У нас более 1000 пользователей, поэтому поисковик каталогов использует подкачку, потому что по умолчанию для AD MaxPageSize равно 1000.

В настоящее время поиск работает «иногда», когда я создаю и отправляю обратно всех 1054 пользователей, а в других случаях он отправляет обратно только 1000. Если он работает один раз, он работает все время. Если он завершается с ошибкой один раз, он завершается с ошибкой все время. Я установил все в операторах using, чтобы убедиться, что объекты уничтожены, но, похоже, он по-прежнему не всегда учитывает атрибут pageSize. По умолчанию, если установлен атрибут pageSize, поисковик должен использовать SizeLimit, равный 0. Я попытался оставить ограничение на размер, установив его равным 0 и установив его равным 100000, и нестабильный результат тот же. Я также попытался уменьшить размер страницы до 250 и получить те же нестабильные результаты. В настоящее время я пытаюсь изменить политику ldap на сервере, чтобы иметь максимальный размер страницы 10000, и я все еще получаю 1000 пользователей с размером страницы поиска до 10000. Не уверен, чего мне здесь не хватает, но любая помощь или направление будут оценены.

     public IEnumerable<StaffInfo> GetStaff(string userId)
    {
        try
        {
            var userList = new List<StaffInfo>();

            using (var directoryEntry = new DirectoryEntry("LDAP://"   _adPath   _adContainer, _quarcAdminUserName, _quarcAdminPassword))
            {
                using (var de = new DirectorySearcher(directoryEntry)
                {
                    Filter = GetDirectorySearcherFilter(LdapFilterOptions.AllUsers),
                    PageSize = 1000,
                    SizeLimit = 0
                })
                {

                    foreach (SearchResult sr in de.FindAll())
                    {
                        try
                        {
                            var userObj = sr.GetDirectoryEntry();
                            var staffInfo = new StaffInfo(userObj);

                            userList.Add(staffInfo);
                        }
                        catch (Exception ex)
                        {
                            Log.Error("AD Search result loop Error", ex);
                        }
                    }
                }
            }

            return userList;
        }
        catch (Exception ex)
        {
            Log.Error("AD get staff try Error", ex);
            return Enumerable.Empty<StaffInfo>();
        }

    }
  

Ответ №1:

Друг вернулся ко мне с приведенным ниже ответом, который мне помог, поэтому я подумал, что поделюсь им и надеюсь, что это поможет кому-нибудь еще с той же проблемой.

Первое, о чем я думаю, это «Используете ли вы доменное имя, например foo.com как _adpath?»

Если это так, то у меня есть довольно хорошая идея. DNS-запрос для Foo.com вернет случайный список всех до 25 контроллеров домена в домене. Если первый DC в этом случайном списке не отвечает или отключен брандмауэром, и вы получаете этот DC от DNS, тогда вы столкнетесь с описанным вами поведением. Поскольку DNS кэшируется на локальном компьютере, вы увидите, что это происходит постоянно в один прекрасный день, а затем не делайте этого на следующий. Это приводящее в бешенство поведение. :/

Вы можете проверить это с помощью трассировки сети, чтобы увидеть, происходит ли это.

Итак, как вы это обходите? Несколько вариантов.

  1. Запрос DNS -> создание списков возвращенных хостов -> Попробуйте первый. Если это не удается, попробуйте следующий. Если вы попали в конец списка, сбой. Если вы сделаете это, регистрируйте каждый независимый сбой шумно, чтобы администраторы не обвиняли вас.

Еще лучше было бы запросить у администраторов AD список серверов ldap и использовать его с подходом, описанным выше.

80% администраторов скажут вам просто использовать доменное имя. Это хорошо, потому что развертывание нового домена будет «просто работать» без необходимости перенастройки.

15% администраторов захотят указать пару контроллеров домена, которые находятся в сети ближе всего к приложению. Это хорошо для производительности, но плохо, если они забудут об этом приложении, когда придет время обновить свой домен.

Остальные 5% на самом деле не имеют значения. 🙂

Следующий момент, который я вижу, это то, что вы используете LDAP, а не LDAP. Это нормально, но есть риск, что вы будете использовать «базовые» привязки. С помощью «базовых» привязок Джо хакер может украсть учетные данные вашей учетной записи с помощью сетевого анализатора. Есть несколько возможных обходных путей. 1. Существует другой конструктор DirectoryEntry, который позволит вам указать «Безопасный» в качестве метода аутентификации. 2. Спросите своих администраторов, можете ли вы использовать LDAP. (более переносимый, на случай, если вам нужно связаться с сервером LDAP, отличным от Active Directory)

Последняя часть касается размера страницы. 1000 должно быть универсальным. Не используйте значение> 5000, иначе вы можете ожидать некоторого беспокойного поведения. т. Е. Это выше, чем ограничение по умолчанию в Windows 2003, а в Windows 2008 размер страницы жестко ограничен 5000, если он не был переопределен с помощью довольно неясного бита в AD, называемого dsHeuristics. http://support.microsoft.com/kb/2009267

Ответ №2:

LDAP по умолчанию настроен на возврат не более 1000. Вы можете изменить этот параметр в домене, из которого вы запрашиваете.