簡體   English   中英

通過Java在嵌套組中查找LDAP用戶

[英]Find LDAP user in nested group through Java

我發現的任何東西都不適合我。 而且我很難找到具有有效代碼的答案,而不僅僅是從另一個站點粘貼搜索過濾器字符串。

試圖進行搜索的相關代碼是:

SearchResult sr = executeSearchSingleResult(ctx, SearchControls.SUBTREE_SCOPE, "dc=mydomain,dc=local", "(&(objectClass=person)(sAMAccountName=admin2))", new String[]{"memberOf"});
if (sr != null) {
    Attribute memberOf = sr.getAttributes().get("memberOf");
    if (memberOf != null) {
        for (int i = 0; i < memberOf.size(); i++) {
            Attributes attributes = ctx.getAttributes(memberOf.get(i).toString(), new String[]{"CN"});
            Attribute attribute = attributes.get("CN");
            if (attribute != null) {
                log.info("member of : " + attribute.get(0));
            }
        }
        for (Enumeration e1 = memberOf.getAll(); e1.hasMoreElements();) {
            String unprocessedGroupDN = e1.nextElement().toString();
            String unprocessedGroupCN = getCN(unprocessedGroupDN);
            //checking something here
        }
    }
}

private static SearchResult executeSearchSingleResult(DirContext ctx, int searchScope, String searchBase, String searchFilter, String[] attributes) throws NamingException {
    NamingEnumeration result = executeSearch(ctx, searchScope, searchBase, searchFilter, attributes);
    SearchResult sr = null;
    try {
        while (result.hasMoreElements()) {
            sr = (SearchResult) result.next();
            break;
        }
    } catch (Exception e) {
        log.error(e, e);
    }
    return sr;
}

private static NamingEnumeration executeSearch(DirContext ctx, int searchScope, String searchBase, String searchFilter, String[] attributes) throws NamingException {
    SearchControls searchCtls = new SearchControls();
    if (attributes != null) {
        searchCtls.setReturningAttributes(attributes);
    }
    searchCtls.setSearchScope(searchScope);
    NamingEnumeration result = ctx.search(searchBase, searchFilter, searchCtls);
    return result;
}

當沒有嵌套組時,這可以正常工作。 但是說我有以下組和用戶結構:

My Admins (dn = CN=My Admins,CN=Users,DC=mydomain,DC=local)
    AdminUser1 (dn = CN=AdminUser 1,CN=Users,DC=mydomain,DC=local)
        AdminGroup1 (dn = CN=AdminGroup 1,CN=Users,DC=,mydomain,DC=local)
            AdminUser2 (dn = CN=AdminUser 2,CN=Users,DC=mydomain,DC=local)

這發現 AdminUser1 就好了。 它找不到 AdminUser2。 我需要做的是發現 AdminUser2 一直回到名為My Admins的最高級別組。

我發現了很多對1.2.840.113556.1.4.1941的引用,但將其放入搜索過濾器的不同方法並沒有幫助。

我需要在代碼和/或搜索過濾器中更改什么才能收集處於任何特定組嵌套深度的特定用戶一直回到最頂層組?

使用類似於以下內容的LDAP_MATCHING_RULE_IN_CHAIN過濾器:

(member:1.2.840.113556.1.4.1941:=(CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))

通常會找到用戶CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET所屬的所有組。

但它很復雜。

  • Microsoft Active Directory 有多種組類型
  • Microsoft Active Directory 具有不同的 LDAP 服務(普通和全局目錄)
  • 限制

任何可能導致組不在結果中顯示的內容。

所以組必須是安全組,你應該使用全局目錄

然后有限制。 當組嵌套“太深”或“太寬”時,LDAP_MATCHING_RULE_IN_CHAIN 類型搜索往往會失敗。 這是太多嵌套級別或成員所屬的太多組。

在 LDAP 中,我們可以在建立連接后查詢用戶是否屬於給定組,您可以使用 member 或 memberOf 屬性進行查詢。

查詢成員屬性:使用的過濾器:(&(Group Member Attribute=Group DN)(objectClass=Group Object class)) 例如:(&(memberOf=CN=group,ou=qa_ou,dc=ppma,dc=org)(對象類=組))

Using member Attribute : filter used : (&(Group Member Attribute=User DN)(objectClass=Group Object class)) 例如:(&(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,對於這些組所屬的組,依此類推。

我們不能在生產中使用 LDAP_MATCHING_RULE_IN_CHAIN,因為當嵌套層次太深時它不起作用,它只適用於 Active Directory。 下面的解決方案與 AD 或 OpenLDAP 獨立工作,我們只需要替換組屬性。

以下是查詢用戶所屬的所有嵌套組的示例代碼:


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