如何获取用户的所有Ldap组,包括JAVA中的嵌套组

时间:2012-06-29 11:09:09

标签: java ldap

我想找到用户所属的所有组,包括嵌套组。 就像用户是A1组的一部分而A1组是A的一部分一样,那么我也希望得到A.

以下是代码,我尝试了variuos filterstrings ...但没有给出预期的输出。

String samAccountName = "group";

String searchFilter = "(&(objectclass=user)(memberof: 1.2.840.113556.1.4.1941:="+samAccountName+"))";

//String searchFilter = "(&(objectCategory=person)(memberOf=CN="+samAccountName+"))";

//String searchFilter = "(&(objectcategory=user)(memberof=CN="+samAccountName+",OU=Users,DC=new,DC=com))";

String searchBase = "DC=new,DC=com";

NamingEnumeration answer = ctx.search(searchBase, searchFilter, ontrols);
             List rolesList = new ArrayList();
            while(answer.hasMoreElements()){
                SearchResult sr = (SearchResult)answer.next();

...

感谢任何帮助。

4 个答案:

答案 0 :(得分:1)

我希望您必须递归搜索用户的memberOf属性列表。例如如果用户具有ldapsearch调用的以下ldif样式结果:

cn: user1
memberOf: CN=group1,DC=foo,DC=example,DC=com
memberOf: CN=group2,DC=foo,DC=example,DC=com

..然后你会想要以递增的ldap搜索递归查找group1group2,依此类推这些组成员的组。

我现在正在做类似的事情,但是在perl中,并从Active Directory获取所有组的所有成员的平面列表。 AD使用objectClass: group而OpenLDAP倾向于使用objectClass: groupOfUniqueNamesobjectClass: posixGroup,具体取决于用途(unix-y客户端的posix组,如Linux box,groupOfUniqueNames组,以获取更多一般信息。)完全取决于客户使用目录中的信息。)

编辑:在AD中还应该有一个名为tokenGroups的属性,其中包含用户的安全组的SID,但这对我不起作用。我猜它是可选的,并没有在我的网站的AD服务器上启用。

答案 1 :(得分:0)

下面的代码可以找到用户所属的组列表。正在使用正在使用的LDAP实现

package pack;

import static javax.naming.directory.SearchControls.SUBTREE_SCOPE;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;

import javax.naming.AuthenticationException;
import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.GrantedAuthorityImpl;

import com.sun.jndi.ldap.LdapCtxFactory;

class App4 
{

public static void main(String[] args) 
{

    String username = "userName";
    String password = "password";
    String serverName = "server";
    String domainName = "comp.BIZ";

    System.out.println("Authenticating " + username + "@" + domainName
            + " through " + serverName + "." + domainName);

    // bind by using the specified username/password
    Hashtable<String,String> props = new Hashtable<String,String>();
    String principalName = username + "@" + domainName;
    props.put(Context.SECURITY_PRINCIPAL, principalName);
    props.put(Context.SECURITY_CREDENTIALS, password);
    DirContext context;

    try {
        context = LdapCtxFactory.getLdapCtxInstance("ldap://" + serverName
                + "." + domainName + '/', props);
        System.out.println("Authentication succeeded!");

        // locate this user's record
        SearchControls controls = new SearchControls();
        controls.setSearchScope(SUBTREE_SCOPE);

        NamingEnumeration<SearchResult> renum = context.search(
                toDC(domainName), "(& (userPrincipalName=" + principalName
                        + ")(objectClass=user))", controls);


        if (!renum.hasMore()) 
        {
            System.out.println("Cannot locate user information for "
                    + username);
            System.exit(1);
        }
        SearchResult result = renum.next();

        List<GrantedAuthority> groups = new ArrayList<GrantedAuthority>();
        Attribute memberOf = result.getAttributes().get("memberOf");
        if (memberOf != null) 
        {// null if this user belongs to no group at
                                // all
            for (int i = 0; i < memberOf.size(); i++) 
            {
                Attributes atts = context.getAttributes(memberOf.get(i)
                        .toString(), new String[] { "CN" });
                Attribute att = atts.get("CN");
                groups.add(new GrantedAuthorityImpl(att.get().toString()));
            }
        }

        context.close();

        System.out.println();
        System.out.println("User belongs to: ");
        Iterator<GrantedAuthority> ig = groups.iterator();
        while (ig.hasNext()) 
        {
            System.out.println("   " + ig.next().toString());
        }

    } catch (AuthenticationException a) 
    {
        System.out.println("Authentication failed: " + a);
        System.exit(1);
    } catch (NamingException e) 
    {
        System.out
                .println("Failed to bind to LDAP / get account information: "
                        + e);
        System.exit(1);
    }
}

private static String toDC(String domainName) 
{
    StringBuilder buf = new StringBuilder();
    for (String token : domainName.split("\\.")) 
    {
        if (token.length() == 0)
            continue; // defensive check
        if (buf.length() > 0)
            buf.append(",");
        buf.append("DC=").append(token);
    }
    return buf.toString();
}

}

答案 2 :(得分:0)

String searchFilter =“(&amp;(objectClass = person)(samaccountname =”+ userName +“))”

我修改了searchFilter并且它有效。

答案 3 :(得分:0)

在 LDAP 中,我们可以在建立连接后查询用户是否属于给定组,您可以使用 member 或 memberOf 属性进行查询。

Query for memberOf Attribute : 
filter used : (&(Group Member Attribute=Group DN)(objectClass=Group Object class))
Ex : (&(memberOf=CN=group,ou=qa_ou,dc=ppma,dc=org)(objectClass=group))

Using member Attribute : 
filter used : (&(Group Member Attribute=User DN)(objectClass=Group Object class))
Ex : (&(member=CN=user,ou=qa_ou,dc=ppma,dc=org)(objectClass=group))

但是您必须使用用户的 member 或 memberOf 属性列表进行递归搜索。例如如果用户具有以下组层次结构:

cn:user1 memberOf: CN=group1,DC=foo,DC=example,DC=com memberOf: CN=group2,DC=foo,DC=example,DC=com

然后,您需要使用额外的 LDAP 搜索递归查找 group1 和 group2,对这些组所属的组依此类推。

以下是查询用户所属的所有嵌套组的示例代码:


import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;

import javax.naming.Context;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;

public class MemberDemo {
    private static final String contextFactory = "com.sun.jndi.ldap.LdapCtxFactory";
    private static final String connectionURL = "ldap://10.224.243.133:389";
    private static final String connectionName = "CN=administrator,CN=users,DC=ppma,DC=org";
    private static final String connectionPassword = "Conleyqa12345";

    public static int nestLevel = 3;
    public static int level = 1;

    // Optional
    private static final String authentication = null;
    private static final String protocol = null;
    private static String userBase = "OU=qa_OU,DC=ppma,DC=org";

    public static void main(String[] args) throws NamingException {
        long start = System.currentTimeMillis();

        Hashtable<String, String> env = new Hashtable<String, String>();

        // Configure our directory context environment.

        env.put(Context.INITIAL_CONTEXT_FACTORY, contextFactory);
        env.put(Context.PROVIDER_URL, connectionURL);
        env.put(Context.SECURITY_PRINCIPAL, connectionName);
        env.put(Context.SECURITY_CREDENTIALS, connectionPassword);
        if (authentication != null)
            env.put(Context.SECURITY_AUTHENTICATION, authentication);
        if (protocol != null)
            env.put(Context.SECURITY_PROTOCOL, protocol);

        InitialDirContext context = new InitialDirContext(env);

        SearchControls constraints = new SearchControls();
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

        Set<String> traversedGroups = new HashSet<String>();
        Set<String> relatedGroups = new HashSet<String>();
        List<String> tempParentColl = new CopyOnWriteArrayList<String>();
        List<String> tempGroups = new ArrayList<String>();

        String loginUser = "CN=qa20Nest,OU=qa_OU,DC=ppma,DC=org";

        String filter = "(&(member=" + loginUser + ")(objectClass=group))";
        tempGroups = findNestedGroups(tempGroups, context, filter, loginUser, constraints,
                tempParentColl, traversedGroups, getUserName(loginUser));
        relatedGroups.addAll(tempGroups);

        System.out.println("Parent Groups :");

        for (String group : relatedGroups) {
            System.out.println(group);
        }
        long end = System.currentTimeMillis();
        long elapsedTime = end - start;
        System.out.println("Total time taken in sec : " + elapsedTime / 1000);

    }

    @SuppressWarnings("rawtypes")
    public static List<String> findNestedGroups(List<String> tempGrpRelations, InitialDirContext context, String filter,
            String groupName, SearchControls constraints, List<String> tempParentColl, Set<String> traversedGrp,
            String groupIdentifier) {
        NamingEnumeration results;
        try {
            traversedGrp.add(groupName);
            results = context.search(userBase, filter, constraints);

            // Fail if no entries found
            if (results == null || !results.hasMore()) {
                System.out.println("No result found for :" + groupName);
                if (tempParentColl.isEmpty()) {
                    return tempGrpRelations;
                } else {
                    tempParentColl.remove(groupName);
                }
            }

            while (results.hasMore()) {
                SearchResult result = (SearchResult) results.next();
                System.out.println("DN - " + result.getNameInNamespace());
                tempParentColl.add(result.getNameInNamespace());
                tempGrpRelations.add(result.getNameInNamespace());
            }

            Iterator<String> itr = tempParentColl.iterator();
            while (itr.hasNext()) {
                String groupDn = itr.next();
                String nfilter = "(&(member=" + groupDn + ")(objectClass=group))";
                tempParentColl.remove(groupDn);
                if (!traversedGrp.contains(groupDn)) {
                    findNestedGroups(tempGrpRelations, context, nfilter, groupDn, constraints, tempParentColl,
                            traversedGrp, getUserName(groupDn));
                }
            }

        } catch (NamingException e) {
            e.printStackTrace();
        }
        return tempGrpRelations;
    }

    public static String getUserName(String cnName) {

        String name = cnName.substring(cnName.indexOf("CN=")).split(",")[0].split("=")[1];
        return name;
    }
}