2009-11-25 3 views
2

Я пытаюсь запросить ActiveDirectory через LDAP, но запрос может содержать пробелы и другие символы, которые могут вызвать проблемы (дефис?)Запрос Active Directory с LDAP фильтр, содержащих пробелы

(&(objectCategory=person)(objectClass=user)(|(&(sn=Bloggs*)(givenName=Jo*))(displayName=Jo Bloggs)) 

Это OR поиск, например, в SQL было бы WHERE (sn LIKE 'Bloggs%' AND givenName LIKE 'Jo%') OR displayName = 'Jo Bloggs'

Однако, когда я пытаюсь запрос LDAP, я получаю сообщение об ошибке: System.ArgumentException: The (&(objectCategory=person)(objectClass=user)(|(&(sn=Bloggs*)(givenName=Jo*))(displayName=Jo Bloggs)) search filter is invalid

код для выполнения поиска:

string userName = "Jo Bloggs"; 
DirectoryEntry adroot = new DirectoryEntry("LDAP://" + Environment.UserDomainName, "user", "password", AuthenticationTypes.Secure); 
DirectorySearcher search = new DirectorySearcher(adroot); 
search.Filter = string.Format("(&(objectCategory=person)(objectClass=user)(|(&(sn={0}*)(givenName={1}*))(displayName={2}))", userName.Split(' ')[1], userName.Split(' ')[0], userName); 

Это только основной поиск, я бы например, поиск других столбцов (название должности, телефон, отдел и т. д.), например WHERE title LIKE '%foo%' OR telephonenumber LIKE '%foo% OR department LIKE '%foo%'

Кроме того, можно ли кэшировать поиск, поэтому ActiveDirectory не получает много обращений от людей, ищущих t для одной и той же вещи?

Это также находит только одну запись, я бы хотел найти и отобразить в репитере все найденные результаты.

+0

Принят больше ответов на мои предыдущие вопросы. Однако есть несколько вопросов, которые не ответили на вопрос (либо ответа нет (например, не может быть сделано, ограничения системы), либо ответы не полностью отвечают на вопрос) – SamWM

ответ

2

Вам не хватает закрывающей круглой скобки. Попробуйте это рабочий пример:

string userName = "Jo Bloggs"; 
string baseQuery = 
    "(&" + 
     "(objectCategory=person)" + 
     "(objectClass=user)" + 
     "(|" + 
      "(&" + 
       "(sn={0}*)" + 
       "(givenName={1}*)" + 
      ")" + 
      "(displayName={2})" + 
     ")" + 
    ")"; // <<< this is missing in your original query 

userName = Regex.Replace(userName, @"[\(\)\*\\]", (match) => 
       { // escape reserved chars 
        return "\\" + ((int)match.Value[0]).ToString("x"); 
       }, RegexOptions.Compiled); 
string query = String.Format(query, userName.Split(' ')[1], 
            userName.Split(' ')[0], userName); 
using (DirectoryEntry entry = new DirectoryEntry(
    "LDAP://" + Environment.UserDomainName, "user", "password", 
    AuthenticationTypes.Secure)) 
{ 
    using (DirectorySearcher ds = 
     new DirectorySearcher(entry, query, null, SearchScope.Subtree)) 
    { 
     SearchResultCollection res = ds.FindAll(); // all matches 
     if (res != null) 
      foreach (SearchResult r in res) 
       Console.WriteLine(user.Properties["displayName"].Value); 
    } 
} 

EDIT: О экранирующих последовательностей, вы должны ссылаться на этот документ: Creating a Query Filter. Я редактирую этот ответ, чтобы отразить эту информацию.

If any of the following special characters must appear in the query filter as literals, they must be replaced by the listed escape sequence.

 
    ASCII  Escape sequence 
character  substitute 
    *   "\2a" 
    (   "\28" 
    )   "\29" 
    \   "\5c" 
    NUL   "\00" 

In addition, arbitrary binary data may be represented using the escape sequence syntax by encoding each byte of binary data with the backslash followed by two hexadecimal digits. For example, the four-byte value 0x00000004 is encoded as "\00\00\00\04" in a filter string.

+0

Отсутствие скобки было причиной код не работает .. написание его на вашем пути (разбивка на строки), упрощает понимание и отладка – SamWM

+0

Что делать, если displayName содержит скобки, например «Джон Смит (PA для директора)» или отдел имеет «Финансы и эффективность»? – SamWM

+0

исправлено, пожалуйста, посмотрите –

0

Существует также другой LINQ к AD http://adlinq.codeplex.com основы, которая реализует несколько IQueryable методов расширения (Single, Имя, фамилия , SingleOrDefault и многие другие) и имеет частые обновления.

Смежные вопросы