简体   繁体   English

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

[英]How to get all Ldap Groups of a user including nested groups in JAVA

I want to find all the groups a user is part of, including nested groups.我想查找用户所属的所有组,包括嵌套组。 Like if user is part of group A1 and group A1 is part of A, then I want to get A as well.就像如果用户是 A1 组的一部分而 A1 组是 A 的一部分,那么我也想获得 A。

Following is code , I have tried variuos filterstrings... but nothing is given expected output.以下是代码,我尝试了各种过滤器字符串......但没有给出预期的输出。

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();

... ...

Any help is appreciated.任何帮助表示赞赏。

I expect you'll have to recursively search the memberOf attribute list for a user.我希望您必须递归搜索用户的 memberOf 属性列表。 eg if a user has the following ldif-style result from an ldapsearch call:例如,如果用户从ldapsearch调用获得以下 ldif 样式的结果:

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

..then you'll want to recursively look up group1 and group2 with additional ldap searches, and so on for groups which those groups are membersOf. ..那么您将需要使用额外的 ldap 搜索递归查找group1group2 ,对于这些组是 membersOf 的组,依此类推。

I'm doing something similar right now, but in perl and to get flat lists of all members of all groups from Active Directory.我现在正在做类似的事情,但是在 perl 中,并从 Active Directory 中获取所有组的所有成员的平面列表。 AD uses objectClass: group whereas OpenLDAP tends to use objectClass: groupOfUniqueNames or perhaps objectClass: posixGroup , depending on the use (posix groups for unix-y clients such as Linux boxes, groupOfUniqueNames groups for more general information. It depends entirely on the clients using the information from the directory). AD 使用objectClass: group而 OpenLDAP 倾向于使用objectClass: groupOfUniqueNamesobjectClass: posixGroup ,具体取决于用途(用于 unix-y 客户端的 posix 组,例如 Linux 机器, groupOfUniqueNames 组以获得更一般的信息。它完全取决于使用的客户端目录中的信息)。

Edit: In AD there is also supposed to be an attribute called tokenGroups which contains the SIDs of security groups for users, but this didn't work for me.编辑:在 AD 中还应该有一个名为tokenGroups的属性,它包含用户的安全组的 SID,但这对我不起作用。 I'm guessing it's optional and not enabled on my site's AD server.我猜它是可选的并且未在我网站的 AD 服务器上启用。

Below code works finding the list of groups that the user belongs to.Sun LDAP implementation is being used下面的代码用于查找用户所属的组列表。正在使用 Sun 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();
}

} }

String searchFilter ="(&(objectClass=person)(samaccountname="+userName+"))" String searchFilter ="(&(objectClass=person)(samaccountname="+userName+"))"

I modidfied the searchFilter and it works.我修改了 searchFilter 并且它有效。

In LDAP we can query if a User belongs to a given group once you have established a connection you can query using either member or memberOf attribute.在 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))

But You'll have to search recursively using the member or memberOf attribute list for a user.但是您必须使用用户的 member 或 memberOf 属性列表递归搜索。 eg if a user has the following group hierarchy :例如,如果用户具有以下组层次结构:

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

then you'll want to recursively lookup group1 and group2 with additional LDAP searches, and so on for groups which those groups are members of.那么您将需要使用额外的 LDAP 搜索递归查找 group1 和 group2,对于这些组所属的组,依此类推。

Below is the sample code to query all the nested groups a User belongs to :以下是查询用户所属的所有嵌套组的示例代码:


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;
    }
}


声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM