解析ldap过滤器以转义特殊字符
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析ldap过滤器以转义特殊字符相关的知识,希望对你有一定的参考价值。
ejb服务将ldap过滤器作为字符串,并从ActiveDirectory返回结果。 问题是,有时属性值包含需要为整个过滤器转义的特殊字符,如下所示: https://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx 以及此处指定的专有名称属性值: https://msdn.microsoft.com/en-us/library/aa366101(v=vs.85).aspx 为了实现此目的,服务必须执行以下操作:
- 分析dn值的字符串,将它们分开并按照dn转义规则转义它们(如果它们尚未转义)。
- 在字符串的其余部分中搜索属性值中的特殊字符,如果它们尚未转义,则按照常规过滤器转义规则对其进行转义。
- 将结果组合为新的转义过滤器并将其传递。
Java native javax.naming.ldap.Rdn
可以逃脱dn值,但不是幂等的。至于其他任务,到目前为止,我一直无法找到一个允许我完成它们的库。
现在我倾向于认为逃避ldap过滤器的工作应该由服务的用户而不是服务本身完成,因为服务很难告诉逃避实际值。此外,在没有经过良好测试的库的情况下解析复杂的字符串(如ldap过滤器)似乎容易出错。
关于如何解决这个问题的任何想法?这个任务可以自动完成吗?
对于转义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(" 00", "\00");
}
这里要记住的最重要的事情是用替换
5C
必须先发生,这样你就不会双重逃避任何角色。否则它非常简单;没有任何特殊的技巧需要注意。
我想指出,这是为了逃避LDAP过滤器中的个别值,而不是整个LDAP过滤器。但是,如果您愿意,可以使用该函数来逃避这样的事情,以便搜索:
LdapEscape("(!(sn=m*))"); // 28!28sn=m2A29
Pluto的答案非常简洁,但非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;
}
以上是关于解析ldap过滤器以转义特殊字符的主要内容,如果未能解决你的问题,请参考以下文章
在我们将其解析为 JSON 之前,Snowflake 如何转义对象数组字符串中的所有特殊字符?