【问题标题】:JNDI ldap search recursiveJNDI ldap 搜索递归
【发布时间】:2015-09-02 04:24:31
【问题描述】:

谁能帮我改进java中的ldap递归搜索?下面是我的代码。我通过的过滤器是filter=(&(IMSI=404201234500021))。目前从 100000 条记录中搜索一条记录需要 19 秒以上。

public List<Map<String, String>> searchRecursive(List<String> sColumns, Map<String, String> searchFilters, int startIndex,
        int amount)
{
    String searchRDN = "";
    List<Map<String, String>> items = new ArrayList<Map<String, String>>();
    Attributes searchAttributes = new BasicAttributes();
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);

    NamingEnumeration<SearchResult> results = null;
    try
    {
             String filter = "";
             if (searchFilters != null)
             {
                 for (Map.Entry<String, String> entry : searchFilters.entrySet())
                 {
                     filter += "(" + entry.getKey() + "=" + entry.getValue() + ")";
                 }
             }    
            filter = "(&" + filter + ")";
            _log.debug("filter="+filter);
            byte[] cookie = null;
            ctx.setRequestControls(new Control[]
                {new PagedResultsControl(amount, cookie, Control.NONCRITICAL)});

           //results = ctx.search(searchRDN, searchAttributes, null);
            results= ctx.search("", filter, ctls);
        if (results != null)
        {
            while (results.hasMore())
            {
                Map<String, String> rowSet = new CaseInsensitiveMap();
                SearchResult searchResult = results.next();
                String rdn = searchResult.getNameInNamespace();
                rowSet.put("baseRDN", rdn);
                NamingEnumeration<? extends Attribute> all = searchResult.getAttributes().getAll();
                while (all.hasMoreElements())
                {
                    Attribute attr = all.nextElement();
                    // attr.getID()
                    NamingEnumeration<?> all2 = attr.getAll();
                    String value = "";
                    while (all2.hasMoreElements())
                    {
                        if (!value.equals(""))
                        {
                            value += ", " + all2.nextElement();
                        }
                        else
                        {
                            value = "" + all2.nextElement();
                        }
                    }
                    rowSet.put(attr.getID(), value);
                }
                items.add(rowSet);
            }
        }
    }
    catch (Throwable e)
    {
        _log.error(e.getMessage());
        _log.debug(e);
    }
    finally
    {
        if (results != null)
        {
            try
            {
                results.close();
            }
            catch (Exception e)
            {
            }
        }
    }
    return items;
}

【问题讨论】:

  • 您能解释一下您的代码在做什么以及为什么要这样做吗?
  • 我想在所有对象类中搜索一个记录条目。共有三个对象类

标签: java ldap jndi openldap


【解决方案1】:

根据 LDAP 树和数据结构,以下一项或多项提示可能会有用:

  1. 从特定的ou= 开始搜索,而不是从根目录开始搜索并减少搜索深度。

    ctx.search("", filter, ctls); 中的"" 替换为ou=people,ou=company,ou=com 之类的DN

  2. 限制搜索结果大小。

    通过ctls.setCountLimit(expected);添加搜索结果大小

  3. 限制收集的属性

    添加一组您感兴趣的属性。

    String[] attributeFilter = { "cn", "mail" }; ctls.setReturningAttributes(attributeFilter);

编辑解释 1.

LDAP 结构就像一棵树:

root
 +- dc=com
  +- dc=company
   +- dc=people
    +- ou=developer
     +- dn=john_doe
    +- ou=manager
     +- dn=jane_foo

如果您要搜索 john_doe,则在 ou=developer,ou=people,ou=company,ou=com 而不是 root(在您的代码中由 "" 表示)开始递归搜索。

EDIT基于评论的示例

root
 +- dc=com
  +- dc=example
   +- IMSI=1
    +- IMSI=1
     +- Context-Identifier=1001

这个数据结构对我来说看起来很奇怪。但根据这些信息,搜索应该从 IMSI=1,dc=example,dc=com 开始。

【讨论】:

  • [root@localhost ~]# grep "rootdn" /usr/local/etc/openldap/slapd.conf # 更新到 rootdn。 (例如,“access to * by * read”)#rootdn 总是可以读写一切! rootdn "cn=Manager,dc=example,dc=com" # 明文密码,特别是对于 rootdn,应该 [root@localhost ~]# 但是当我在 ctx.search 中添加这个时,我得到错误代码 32 - 没有这样的对象
  • rootDN 类似于 root 用户。此 DN 将用于验证您的连接并在 LDAP 实例上搜索。我会在我的回答中更好地解释它。
  • 实际上是 ldap 的新手。你能帮我找到我需要使用的值吗。
  • 我会尽力帮助您,但我需要有关您的 LDAP 结构的更多信息。请提供searchResult.getNameInNamespace(); 的结果之一。
  • getNameInNamespace=IMSI=404201234500001,IMSI=404201234500001,dc=example,dc=com
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-10
  • 2019-03-12
相关资源
最近更新 更多