当前位置: 首页 > 知识库问答 >
问题:

解析ldap筛选器以转义特殊字符

张逸清
2023-03-14



问题是,有时属性值包含需要对此处指定的整个过滤器进行转义的特殊字符:
https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85). aspx
和此处指定的专有名称ATITBUTE值:
https://msdn.microsoft.com/en-us/library/aa366101(v=vs.85). aspx
为了实现这一点,服务必须执行以下操作:

  1. 分析dn值的字符串,将它们分开并根据dn转义规则转义它们,如果它们尚未转义。
  2. 在字符串的其余部分搜索属性值中的特殊字符,如果它们尚未转义,则按照通用过滤器转义规则转义它们。
  3. 将结果合并为新的转义过滤器并将其传递。

Java本机javax.naming.ldap.Rdn转义dn值很好,但不是幂等的。至于其他任务,到目前为止,我还没有找到一个可以让我完成它们的库。

现在我倾向于认为转义ldap过滤器的工作应该由服务的用户完成,而不是由服务本身完成,因为服务很难区分转义与实际值。此外,在没有经过良好测试的库的情况下解析复杂的字符串,例如ldap过滤器,在我看来似乎很容易出错。

关于如何解决这个问题有什么想法吗?这个任务可以自动化吗?

共有3个答案

商德泽
2023-03-14

如果调用方提供的LDAP筛选器表示用于查询的最终筛选器,则无法可靠地转义该筛选器中的值。考虑调用方组装的以下过滤器:

String value = "*)(objectClass=*";
String filter = "(|(attr1=constvalue)(attr2=" + value + "))";
search(filter);

生成的过滤器匹配所有对象,因为代码不会转义value

(|(attr1=constvalue)(attr2=*)(objectClass=*))

没有办法根据最终过滤器转义value,因为无法再识别开始和结束位置。

为了解决这种模糊性和滤波器注入问题,必须在构建滤波器时转义输入值,而不是事后转义。然而,这并不意味着调用者必须直接处理转义细节——这很容易出错,所以我不建议这样做。

EJB处理转义所需要的只是知道所需的过滤器,包括占位符而不是实际值和值列表。Java的DirContext已经提供了一种可以利用的机制<代码>DirContext。搜索有一个表示过滤器模板的参数,该模板可以包含占位符,还有一个表示相应值列表的参数。

这样,上述示例将变成:

String value = "*)(objectClass=*";
String filter = "(|(attr1=constvalue)(attr2={0}))";
search(filter, new String[] { value });

search的实现:

dircontext.search(basedn, filter, valuearray, null);

这是我能想到的最好的妥协。它完全解决了LDAP过滤器注入问题,但不需要调用方处理转义,调用方只需提供一个过滤器模板和一个值列表。

通常,使用库工具进行转义应该优于自定义代码,以确保正确处理所有情况。其他两个答案说明了这一点。

章宏峻
2023-03-14

冥王星给出的答案非常简洁,但非ASCII UTF-8字符(例如é、á、ö等)也需要特殊处理。这是我详细的解决方案。

/** 
 * Filter components need to escape special chars.
 * Note that each piece of the filter needs to be escaped, 
 * not the whole filter expression, for example:
 * 
 * "(&(cn="+ esc("Admins") +")(member="+ esc("CN=Doe\\, Jöhn,OU=ImPeople,DC=ds,DC=augur,DC=com") +"))"
 * 
 * @see Oracle Directory Server Enterprise Edition 11g Reference doc
 * @see http://docs.oracle.com/cd/E29127_01/doc.111170/e28969/ds-ldif-search-filters.htm#gdxoy
 * @param s A String field within the search expression
 * @return The escaped string, safe for use in the search expression.
 */
public static String esc(String s)
{
    if(s == null) return "";
    StringBuilder sb = new StringBuilder(s.length());
    for (byte c : s.getBytes(StandardCharsets.UTF_8))
    {
        if (c=='\\') { sb.append("\\5c"); }
        else if (c=='*') { sb.append("\\2a"); }
        else if (c=='(') { sb.append("\\28"); }
        else if (c==')') { sb.append("\\29"); }
        else if (c==0) { sb.append("\\00"); }
        else if ((c&0xff)>127) { sb.append("\\").append(to2CharHexString((c&0xff))); } // UTF-8's non-7-bit characters, e.g. é, á, etc...
        else { sb.append((char)c); }
    }
    return sb.toString();
}

/** 
 * @return The least significant 16 bits as a two-character hex string, 
 * padded by a leading '0' if necessary.
 */
public static String to2CharHexString(int i)
{
    String s = Integer.toHexString(i & 0xff);
    if (s.length()==1) return "0"+s;
    else return s;
}
许奇
2023-03-14

为了转义LDAP过滤器,我依靠此页面编写了以下代码:http://social.technet.microsoft.com/wiki/contents/articles/5392.active-directory-ldap-syntax-filters.aspx#Special_Characters

String LdapEscape(String ldap)
{
    if(ldap == null) return "";
    return ldap.replace("\\", "\\5C").replace("*", "\\2A").replace("(", "\\28").replace(")", "\\29").replace("\000", "\\00");
}

这里要记住的最重要的事情是必须首先将\替换为\5C,这样您就不会对任何字符进行双重转义。否则这很简单;没有任何特殊的技巧需要注意。

我想指出的是,这是为了转义放置在LDAP过滤器中的单个值,而不是整个LDAP过滤器。但是,如果您愿意,可以使用该函数来转义类似的内容,以便可以搜索:

LdapEscape("(!(sn=m*))"); // \28!\28sn=m\2A\29
 类似资料:
  • 正如我们所看到的,一个反斜杠 "\" 是用来表示匹配字符类的。所以它是一个特殊字符。 还存在其它的特殊字符,这些字符在正则表达式中有特殊的含义。它们可以被用来做更加强大的搜索。 这里是包含所有特殊字符的列表:[ \ ^ $ . | ? * + ( )。 现在并不需要尝试去记住它们 —— 当我们分别处理其中的每一个时,你自然而然就会记住它们。 转义 如果要把特殊字符作为常规字符来使用,只需要在它前面

  • 问题内容: 我想电视机1 ® 2的outputText: 什么不对?我大写。 问题答案: 您可以选择以下之一 在您最初的建议中,您放错了位置,应该在 您也可以完全删除(但您的(R)不会很小) 最后,您可以直接使用它而无需转义

  • 问题内容: 根据选择器文档,必须使用双反斜杠等进行转义。 我有一个这样创建的选择器(假设属性在此示例中)。 我可以写一个正则表达式为我逃脱括号吗? 问题答案: 如果您希望某些东西具有任何价值,请尝试以下操作: 这可以通过用两个反斜杠转义jQuery文档的“ 选择器”页面上列出的所有CSS元字符来工作。 请记住,在您的情况下,无需执行此类棘手的操作。您可以使用过滤器功能选择具有给定值的所有选项元素,

  • 问题内容: 我想使用SAX解析器解析xml文件中的一些数据。我的xml如下: 为了解析此数据,我扩展了DefaultHandler。 解析后的输出为: 为什么发生这种情况而不是得到: 问题答案: 我的猜测是,您将每次调用都视为交付元素的完整文本。您应该对处理程序进行编码,以便连续调用以累积文本,并且仅在事件发生时捕获它:

  • 本文向大家介绍Shell命令行中特殊字符与其转义详解(去除特殊含义),包括了Shell命令行中特殊字符与其转义详解(去除特殊含义)的使用技巧和注意事项,需要的朋友参考一下 特殊符号及其转义 大家都知道在一个shell命令是由命令名和它的参数组成的, 比如 cat testfile, 其中cat是命令名, testfile是参数. shell将参数testfile传递给cat命令. 但是, 如果参数

  • 问题内容: Oracle中是否有一种简单的方法来转义SQL语句中的特殊字符?(即%,&,’)我看到了有关手动转义字符的链接,但我认为Oracle可能提供了一种更简便的方法。 注意:我正在通过ORM生成动态SQL select语句。 问题答案: 如果使用绑定变量和ORM,则应自动处理嵌入的单引号和“&”号。这些是SQL * Plus或SQL * Developer中的特殊字符。 要在查找文字字符%和