Несколько подключений LDAP с классом C # DirectoryEntry

Я использую класс DirectoryEntry для аутентификации LDAP. Он отлично работает, когда я использую одну строку подключения LDAP. Но как только я начинаю выполнять код в нескольких потоках для нескольких строк подключения LDAP, он начинает случайным образом генерировать исключение аутентификации, даже если имя пользователя и пароль верны. Я использую следующий код.

public bool IsAuthenticated(string path, string domain, string group, string username, string pwd)
{
    string domainAndUsername = domain + @"\" + username;

    LogManager.Application.DebugFormat("Inside IsAuthenticated for User {0} from Domain {1} and Group {2} of Path {3} ", username, domain, group, path);

    try
    {
        using (DirectoryEntry entry = new DirectoryEntry(path, domainAndUsername, pwd))
        {

            entry.AuthenticationType = AuthenticationTypes.Secure;
            entry.RefreshCache();
            //Bind to the native AdsObject to force authentication.
            object obj = entry.NativeObject;

            using (DirectorySearcher search = new DirectorySearcher(entry))
            {

                search.Filter = "(SAMAccountName=" + username + ")";
                search.PropertiesToLoad.Add("cn");
                SearchResult result = search.FindOne();

                if (null == result)
                {
                    LogManager.Application.ErrorLogFormat("User {0} is not available in Domain {1}", username, domain);
                    return false;
                }
            }
            LogManager.Application.DebugFormat("User {0} is available in Domain {1}", username, domain);
            return true;
        }
    }
    catch (Exception ex)
    {
        LogManager.Application.ErrorLogFormat("Exception occured while authenticating user {0} : Error {1} ", username, ex.Message);
        return false;
    }
}

Эта функция предоставляется через веб-сервис ASMX. Эта веб-служба выполняется одновременно несколькими пользователями. Каждый пользователь предоставляет путь (LDAP://{IP}/DC={Domain},DC=COM), домен и учетные данные. Таким образом, одновременно выполняется код для нескольких соединений LDAP.

ОБНОВИТЬ:

Это функция веб-службы ASMX, которая вызывает указанную выше функцию:

public class ValidateUserService : System.Web.Services.WebService
{

    [WebMethod]
    public Models.AuthenticationToken IsUserAuthenticated(string username, string password, string partnerName)
    {
        string path;
        string group;
        string domain;
        // Internal Code to pull the domain name, group and path from the db with help of partnerName.
        //each partner will have different path (LDAP conenction string) and domain.
        bool isAuthenticated = IsAuthenticated(path, domain, group, username, password);

    }
}

Я заметил, что когда несколько пользователей из разных AD пытаются выполнить этот код, он случайным образом выдает ошибку аутентификации. Как видите, в коде нет статической переменной. Таким образом, для каждого вызова создается новый экземпляр DirectoryEntry. Таким образом, на более высоком уровне этот код настройки должен работать с несколькими соединениями LDAP.

Сказав это, кто-нибудь видел такое поведение? Обменивается ли .net framework внутренними данными между несколькими DirectoryEntry экземплярами? Может ли один процесс иметь несколько одновременных подключений LDAP? Любая помощь, предложение или указатели приветствуются.


person Amey    schedule 21.04.2015    source источник
comment
в какой строке ваш код выдает исключение? Предоставляется ли метод IsAuthenticated через веб-сервис ASMX или нет?   -  person VMAtm    schedule 21.04.2015
comment
Над функцией IsAuthenticated есть функция-оболочка. Эта функция предоставляется через веб-службу ASMX. Исключение Ошибка входа в систему: при выполнении строки entry.RefreshCache () обнаружено неизвестное имя пользователя или неверный пароль. Когда я вызываю свою веб-службу ASMX в нескольких потоках (каждый поток имеет другую строку подключения LDAP) с помощью JMeter, случайным образом запрос не выполняется с указанным выше исключением.   -  person Amey    schedule 21.04.2015
comment
Можете ли вы показать код, который вы использовали для вызова IsAuthenticated?   -  person VMAtm    schedule 21.04.2015
comment
Я обновил свой вопрос кодом функции, вызывающей указанный выше метод.   -  person Amey    schedule 21.04.2015


Ответы (1)


Я нашел способ решения проблемы и публикую его, если кто-то еще сталкивается с такой же проблемой. Я пробовал следующие методы работы с AD / LDAP:

  1. Использование класса DirectoryEntry
  2. Использование LdapConnection и класса NetworkCredential
  3. Использование класса PrincipalContext

Я заметил, что если приложение работает с несколькими серверами AD одновременно и открывает одновременные соединения с несколькими серверами AD, то метод DirectoryEntry не работает. Для действительных учетных данных генерируется исключение «несанкционированный доступ». Я предполагаю, что некоторые данные / переменные являются общими, и он пытается аутентифицировать пользователя на неправильном сервере AD. Я изучил код сборки и убедился, что он использует статические переменные. Это могло быть настоящей причиной, но не на 100%. Мой обходной путь - использовать два других метода, если приложению необходимо открывать одновременные подключения к нескольким серверам AD. Я тестировал его примерно с 10 одновременными подключениями примерно за последние шесть месяцев, и он работает нормально.

Надеюсь, это поможет, если кто-то столкнется с той же проблемой.

person Amey    schedule 19.02.2016