2009-11-25 14 views
2

Je tente d'interroger ActiveDirectory via LDAP, mais la requête peut contenir des espaces ou d'autres caractères qui peuvent causer des problèmes (des traits d'union?)Interrogation Active Directory avec des espaces contenant des filtres LDAP

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

Il est une OU recherche par exemple dans SQL il serait WHERE (sn LIKE 'Bloggs%' AND givenName LIKE 'Jo%') OR displayName = 'Jo Bloggs'

Cependant, lorsque je tente la requête LDAP, je reçois une erreur: System.ArgumentException: The (&(objectCategory=person)(objectClass=user)(|(&(sn=Bloggs*)(givenName=Jo*))(displayName=Jo Bloggs)) search filter is invalid

code pour effectuer la recherche:

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); 

Ceci est juste une recherche de base, je vous souhaitez également rechercher d'autres colonnes (titre du poste, numéro de téléphone, département, etc.), par ex. WHERE title LIKE '%foo%' OR telephonenumber LIKE '%foo% OR department LIKE '%foo%'

De même, est-ce que je peux mettre en cache la recherche, donc ActiveDirectory ne reçoit pas beaucoup de hits de la part des personnes qui cherchent t la même chose?

Cela trouve également une seule entrée, je voudrais rechercher et afficher dans un répéteur tous les résultats qui sont trouvés.

+0

Accepté plus de réponses à mes questions précédentes maintenant. Cependant, il y en a quelques-uns qui n'ont pas répondu à la question (soit il n'y a pas de réponse (par exemple ne peut pas être fait, limitation du système), soit les réponses ne répondent pas complètement à la question) – SamWM

Répondre

2

Il vous manque une parenthèse fermante. Essayez cet exemple de travail:

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: A propos des séquences d'échappement, vous devez vous référer à ce document: Creating a Query Filter. Je modifie cette réponse pour refléter cette information.

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

le code ne fonctionne pas .. l'écrire dans votre chemin (se briser en lignes), le rend plus facile à comprendre et déboguer – SamWM

+0

Que faire si displayName contient des crochets, par exemple 'John Smith (PA to Director)' ou département a & - 'Finance & Performance'? – SamWM

+0

fixé cela, s'il vous plaît jeter un oeil –

0

Il y a aussi une autre LINQ au cadre AD http://adlinq.codeplex.com qui met en œuvre plusieurs des méthodes d'extension IQueryable (Single, First, Last , SingleOrDefault et beaucoup plus) et a des mises à jour fréquentes.

Questions connexes