2013-02-19 3 views
1

У меня есть некоторый рабочий код LDAP, в котором мы переписываем найденного пользователя, чтобы проверить пользователя, используя его выдающееся имя. Фактически это то, что происходит:OpenLdap C# bind с экранированными символами в Distinguished Name

  string userDn = @"cn=Feat Studentl+umanroleid=302432,ou=Faculty of Engineering & Physical Sciences Administration,ou=Faculty of Engineering & Physical Sciences,ou=People,o=University of TestSite,c=GB"; 
      string fullPath = @"LDAP://surinam.testsite.ac.uk:636/" + userDn; 

      DirectoryEntry authUser = new DirectoryEntry(fullPath, userDn, "mypassword", AuthenticationTypes.None); 

      authUser.RefreshCache(); 

Однако это приводит к ошибке неизвестная ошибка 80005000 при DirectoryEntry.Bind()

я подозревал, что проблема может быть, что DN имеет «+» и «=» в атрибуте CN. Поэтому после того, как выяснилось, что способ избежать этого должна быть с \ и шестнадцатеричное значение символа я попытался это:

  string userDn = @"cn=Feat Studentl\2Bumanroleid\3D302432,ou=Faculty of Engineering & Physical Sciences Administration,ou=Faculty of Engineering & Physical Sciences,ou=People,o=University of TestSite,c=GB"; 

Однако я получаю ошибку:

Войти провал: неизвестное имя пользователя или плохо password

Я предполагаю, что это потому, что теперь он доволен запросом, но по какой-то причине он не соответствует DN пользователей.

Есть ли все-таки вокруг этого?

ответ

1

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

В настройках вашего кода параметры AuthenticationTypes на «None» заставляют запись сделать Simple bind на основе DN, который вы предоставляете. Так как ваш, включая имя сервера как часть пути, я хотел бы попробовать использовать тип ServerBind аутентификации вместо этого, как это:

string LdapPath = ("LDAP://" + ldapUrl + "/" + Domain); 

//Build the user and issue the Refresh bind 
var dirEntry = new DirectoryEntry 
        { 
         Path = LdapPath, 
         Username = _usernameToVerify, 
         Password = _passwordToVerify, 
         AuthenticationType = AuthenticationTypes.ServerBind 
        }; 

//This will load any available properties for the user 
dirEntry.RefreshCache(); 

Кроме того, похоже, что вы делаете этот вызов в безопасный порт LDAP (636), поэтому убедитесь, что вы также включать AuthenticationTypes.SecureSocketsLayer вместе с ServerBind mechansim:

AuthenticationType = AuthenticationTypes.ServerBind | AuthenticationTypes.SecureSocketsLayer 

Надеется, что это помогает!

+0

благодарит Грегори. Я попробовал ваш пример, и я уверен, что он поможет другим, но для меня он все еще дал ошибку 80005000 внутри. Я опубликовал пример DirectoryServices более низкого уровня, который мне удалось получить. – user1444886

0

Мне пришлось прибегнуть к копанию старого проекта DLL, который был настроен для одного клиента.

Мне удалось заставить его работать. Похоже, вам нужно обратиться к этим низкоуровневым подпрограммам служб каталогов, если у вас есть DN с escape-символами. (Обратите внимание, что в реальной жизни DN получается путем начального поиска пользователя с помощью пользователя, создающего DirectorySearcher и выполняющего FindOne)

string userDn = @"cn=Feat Studentl+umanroleid=302432,ou=Faculty of Engineering & Physical Sciences Administration,ou=Faculty of Engineering & Physical Sciences,ou=People,o=University of TestSite,c=GB"; 
string basicUrl = @"surinam.testsite.ac.uk:636"; 



    var ldapConnection = new LdapConnection(basicUrl); 
    ldapConnection.AuthType = AuthType.Basic; 
    LdapSessionOptions options = ldapConnection.SessionOptions; 
    options.ProtocolVersion = 3; 
    options.SecureSocketLayer = true; 

    NetworkCredential credential = new NetworkCredential(userDn, password);        
    ldapConnection.Credential = credential; 

    try 
    { 
     ldapConnection.Bind(); 
     Console.WriteLine("bind succeeded "); 
    } 
    catch (LdapException e) 
    { 
     if (e.ErrorCode == 49) 
     { 
      Console.WriteLine("bind failed "); 
     } 
     else 
     { 
      Console.WriteLine("unexpected result " + e.ErrorCode); 
     } 
    } 
    catch (DirectoryOperationException e) 
    { 
     Console.WriteLine("unexpected error " + e.Message); 
    } 
Смежные вопросы