首页 > 解决方案 > 试图通过 Java 从大型 AD 组中提取用户列表 - 只返回 1500 个 - 我怎样才能获得所有用户列表?

问题描述

试图通过 Java 从大型 AD 组中提取用户列表 - 但只能获得 1500 个 - 我怎样才能获得所有用户?

// Step1 method  - Pulling ADGroups from Active Directory
private static void getADGroups() {
    Hashtable<String, Object> env = new Hashtable<String, Object>(11);
    env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
    env.put(Context.PROVIDER_URL, "ldap://");
    env.put(Context.SECURITY_PRINCIPAL, "xxxx");
    env.put(Context.SECURITY_CREDENTIALS, "1233");
    env.put(Context.REFERRAL, "follow");

    LdapContext ctx = null;

    try {
        ctx = new InitialLdapContext(env, null);

        // Activate paged results
        int pageSize = 10000;
        byte[] cookie = null;
        ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, Control.NONCRITICAL) });
        int total;

        do {
            SearchControls searchControls = new SearchControls();
            searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            String[] attrIDs = { "cn" };
            searchControls.setReturningAttributes(attrIDs);

            String searchBase = "OU=Groups,DC=cof,DC=ds,DC=com";
            String searchFilter = "CN=*Ranger*";
            /* perform the search */
            NamingEnumeration results = ctx.search(searchBase, searchFilter, searchControls);

            /* for each entry print out name + all attrs and values */
            int count = 0;
            while (results != null && results.hasMore()) {
                SearchResult entry = (SearchResult) results.next();
                //System.out.println(count + ")" + entry.getName());
                count = count + 1;
                String gname = entry.getName();
                //System.out.println("gname before split " + gname);
                String[] gnames = gname.split(",");
                gname = gnames[0];
                //System.out.println("gname after split - 1 " + gname);
                gname = gname.substring(3);
                //System.out.println("gname after split - 2 " + gname);
                groups.add(gname);
            }
            //System.out.println("count : " + count);

            // Examine the paged results control response
            Control[] controls = ctx.getResponseControls();
            //System.out.println("controls-size : " + controls.length);

            if (controls != null) {
                for (int i = 0; i < controls.length; i++) {
                    if (controls[i] instanceof PagedResultsResponseControl) {
                        PagedResultsResponseControl prrc = (PagedResultsResponseControl) controls[i];
                        total = prrc.getResultSize();

                        //System.out.println("total : " + total);

                        if (total != 0) {
                            //System.out.println("***************** 

                        cookie = prrc.getCookie();
                        //System.out.println("cookie : " + cookie);
                    }
                }
            } else {
                System.out.println("No controls were sent from the server");
            }

            // Re-activate paged results
            ctx.setRequestControls(new Control[] { new PagedResultsControl(pageSize, cookie, Control.CRITICAL) });

        } while (cookie != null);

    } catch (NamingException e) {
        System.out.println("PagedSearch failed." + e.getMessage());
        e.printStackTrace();
    } catch (IOException ie) {
        System.out.println("PagedSearch failed." + ie.getMessage());
        ie.printStackTrace();
    } finally {
        try {
            ctx.close();
        } catch (NamingException e) {
            System.out.println("PagedSearch failed (error occured in closing context)." + e.getMessage());
            e.printStackTrace();
        }
    }

}

// Step2 method - to pull users from ADgroups that we got for above
    private static void getGroupMembers(String groupName) {
        searchBase = "Ou=users";

        String returnedAtts[] = { "member" };
        searchControls.setReturningAttributes(returnedAtts);

        searchFilter = String.format("(cn=%s)", groupName);
        // System.out.println(searchFilter);

        getSearchResult();
        filterSearchResultsForGroupMembers(groupName);
    } // end of method.
`

标签: javaactive-directory

解决方案


关键是您请求member属性的位置。如果您准确地返回 1500 个结果,您就知道可能还有更多。这是您请求下一批的方式:

String[] returnedAtts = { "member;range=1500-*" };

然后,如果您再次获得正好 1500,则需要要求更多(`member;range=3000-*1)。继续要求更多,直到你得到少于 1500 的回报。

所以设置一个带有计数器的循环并在范围字符串中使用该计数器。

这里有一个完整的示例(在页面中搜索“setReturningAttributes”以找到该部分代码):https ://community.oracle.com/thread/1157644


推荐阅读