简体   繁体   English

使用包含空格的LDAP过滤器查询Active Directory

[英]Querying Active Directory with LDAP filter containing spaces

I am attempting to query ActiveDirectory via LDAP, but the query may contain spaces or other characters that may cause problems (hyphens?) 我正在尝试通过LDAP查询ActiveDirectory,但查询中可能包含空格或其他可能引起问题的字符(连字符)。

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

It is an OR search eg in SQL it would be WHERE (sn LIKE 'Bloggs%' AND givenName LIKE 'Jo%') OR displayName = 'Jo Bloggs' 这是一个OR搜索,例如在SQL中它将是WHERE (sn LIKE 'Bloggs%' AND givenName LIKE 'Jo%') OR displayName = 'Jo Bloggs'

However, when I try the LDAP query, I get an error: System.ArgumentException: The (&(objectCategory=person)(objectClass=user)(|(&(sn=Bloggs*)(givenName=Jo*))(displayName=Jo Bloggs)) search filter is invalid 但是,当我尝试LDAP查询时,出现错误: System.ArgumentException: The (&(objectCategory=person)(objectClass=user)(|(&(sn=Bloggs*)(givenName=Jo*))(displayName=Jo Bloggs)) search filter is invalid

Code for performing search: 执行搜索的代码:

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

This is just a basic search, I would like to search other columns as well (Job Title, Telephone, Department etc), eg WHERE title LIKE '%foo%' OR telephonenumber LIKE '%foo% OR department LIKE '%foo%' 这只是一个基本搜索,我也想搜索其他列(职位,电话,部门等),例如WHERE title LIKE '%foo%' OR telephonenumber LIKE '%foo% OR department LIKE '%foo%'

Also, could I cache the search, so ActiveDirectory doesn't get a lot of hits from people searching t for the same thing? 另外,我是否可以缓存搜索,所以ActiveDirectory不会因搜索同一事物的人而获得很多匹配?

This also only finds one entry, I would like to search and display in a repeater all results that are found. 这也只找到一个条目,我想搜索并在转发器中显示找到的所有结果。

You're missing a closing parenthesis. 您缺少右括号。 Try this working example: 尝试以下工作示例:

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: About escape sequences, you should refer to this document: Creating a Query Filter . 编辑:关于转义序列,您应该参考此文档: 创建查询过滤器 I edit this answer to reflect that 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. 例如,四字节值0x00000004在过滤器字符串中编码为“ \\ 00 \\ 00 \\ 00 \\ 04”。

还有另一个LINQ to AD http://adlinq.codeplex.com框架,该框架实现了更多的IQueryable扩展方法(Single,First,Last,SingleOrDefault等),并且具有经常更新的功能。

为什么不使用Linq到AD进行搜索-http://linqtoad.codeplex.com/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM