【问题标题】:Forward slashes in the names returned by JNDI query to LDAP serverJNDI 查询返回到 LDAP 服务器的名称中的正斜杠
【发布时间】:2012-07-27 15:04:48
【问题描述】:

我需要对 LDAP 目录服务器进行多次查询,并且我正在使用 JNDI 目录工具。然后我需要使用它们的专有名称对查询结果中的对象进行一些处理。服务器返回的某些条目包含正斜杠字符,因此 JNDI 使用双引号对整个名称进行转义:

NamingEnumeration<SearchResult> results = dirContext.search(queryRoot, queryFilter, controls);
for (SearchResult result : Collections.list(results)) {
    String objectName = result.getName();
    System.out.println(objectName);
}

如果查询结果中的一个对象有一个名称,比如'b=id/10,a=1',它会像这样打印

"b=id/10,a=1"

注意名称周围的双引号。由于这些引号,我无法直接从中创建javax.naming.ldap.LdapName:它以NamingException "Invalid name" 失败。

我知道我可以手动删除这些引号,但这感觉很老套。有没有办法避免这种逃避?或者也许有更清洁的方法来做我需要的事情?

附:有趣的是,official JNDI tutorial 建议使用LdapName 来实现“简单的名称操作”,甚至提到了转义问题,但没有提供有关上述问题的任何链接。

【问题讨论】:

    标签: java escaping ldap jndi


    【解决方案1】:

    如果AttributeValue 具有特定于 LDAP 的语法,则字符将被转换(使用定义的语法规范)为 UTF-8,并且只有以下字符必须转义:

    • ' '(空格)在字符串的开头
    • ' '(空格)在字符串的末尾
    • '"'
    • '+'(加号表示多值RDN)
    • ,(逗号分隔专有名称的组成部分)
    • ;
    • &lt;
    • &gt;
    • \

    正斜杠是一个有效字符,不需要转义,因此它必须由应用程序和该应用程序使用的 API 处理。正如您所指出的,正斜杠对 JNDI 具有“特殊含义”。 JNDI 在许多方面都设计得很差,这只是众多方面之一。考虑将UnboundID LDAP SDK 用于新代码。

    例如,添加以下条目:

    dn: uid=abc/def,ou=people,dc=example,dc=com
    objectClass: top
    objectClass: person
    objectClass: inetOrgPerson
    uid: abc/def
    cn: abc/def
    sn: abc/def
    userPassword: this entry is used to test http://stackoverflow.com/questions/11690529/forward-slashes-in-the-names-returned-by-jndi-query-to-ldap-server
    

    检索刚刚添加的条目:

    ldapsearch -h localhost -p 10389 -D 'cn=RootDn'  -b dc=example,dc=com -s sub '(uid=abc/def)' 1.1
    Enter bind password: 
    version: 1
    dn: uid=abc/def,ou=people,dc=example,dc=com
    

    另见

    【讨论】:

    • 感谢您的回答。不幸的是,我不能使用除 JNDI 之外的任何东西,因为我无法向项目添加新的外部依赖项。所以,基本上你是说不可能以干净的方式克服这个问题?真可惜……
    【解决方案2】:

    SearchResult.getName() 返回的搜索结果格式为CompositeName。尝试像这样使用它:

    Name itemPart = new CompositeName(result.getName())
    Name absoluteName = new LdapName(myBasePath).addAll(itemPart)
    // or
    String sAbsoluteName = ctx.composeName(new LdapName(myBasePath), itemPart)
    

    奇怪的转义将从absoluteName中删除。

    【讨论】:

      猜你喜欢
      • 2014-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-17
      • 2021-01-01
      • 1970-01-01
      相关资源
      最近更新 更多