Java JNDI LDAP组搜索仅返回一个结果

时间:2015-03-22 00:18:54

标签: ldap jndi openldap

我需要获取userDN的组名。我正在尝试此代码,但无法正常工作,因为ctx.search()将为每个组只返回一个成员。我的意思是,即使我的一些组有多个用户作为成员(使用成员,而不是memberOf),search()将只返回一个。

(我使用OpenLDAP作为LDAP服务器)

最后,我的代码不会返回所提供的userDN的所有组,因为找不到所有匹配项。

感谢您的帮助。

    public Set<String> getLDAPGroupNames(String userDN) throws NamingException {
    Set<String> userRoleNames = new HashSet<>();
    if (isLDAPUserRepositoryEnabled()) {
        for (String roleName : getLDAPGroupNames()) {
            SearchControls constraints = new SearchControls();
            constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
            constraints.setReturningAttributes(new String[] { "member" });
            constraints.setCountLimit(100);
            // First input parameter is search bas, it can be "CN=Users,DC=YourDomain,DC=com"
            // Second Attribute can be uid=username
            LdapContext ctx = getLdapContext();
            try {
                NamingEnumeration<SearchResult> answer = ctx.search(ldapGroupContextDN, "cn=" + roleName, constraints);
                while (answer.hasMore()) {
                    NamingEnumeration<? extends Attribute> attributes = answer.next().getAttributes().getAll();// FIXME Only returns first of the member entry for the group.
                    while (attributes.hasMore()) {
                        Attribute attribute = attributes.next();
                        if (userDN.equalsIgnoreCase((String) attribute.get()))
                            userRoleNames.add(roleName);
                    }
                }
            } finally {
                ctx.close();
            }
        }
    } else
        throw new IllegalStateException("Can't return LDAP group names. No LDAP Context enabled.");
    return userRoleNames;
}

2 个答案:

答案 0 :(得分:1)

我知道这是一个老问题,但我有同样的问题,并找到了解决方案。我把它包括在这里,以便其他人可以受益。

JNDI确实处理多值属性。我正在使用以下内容来收集所有内容 组的成员,而不是查找用户所属的组。也就是说,userRoleNames具有组中的用户,而不是用户的角色。如果您想要特定用户拥有的角色(即用户所属的组),则可以使用EJP指出的解决方案。)

解决方案是改变

 while (attributes.hasMore()) {
                    Attribute attribute = attributes.next();
                    if (userDN.equalsIgnoreCase((String) attribute.get()))
                        userRoleNames.add(roleName);
 }

 while (attributes.hasMore()) {
     Attribute attribute = attributes.next();
     if ("member".equalsIgnoreCase(attribute.getID())){
            for (NamingEnumeration<Object> e = (NamingEnumeration<Object>)attribute.getAll(); e.hasMore(); ){
                    Object v = e.next();
                    userRoleNames.add( v instanceof byte[]? new String((byte[])v):v.toString());
            }
        }                
}

答案 1 :(得分:0)

过滤器应为"(&(cn={0})(member={1}))",过滤器参数为{roleName, userDN},您应删除自己检查userDN的部分代码。然后,只返回将该用户作为成员的组,您需要做的就是保存它们。