如何通过Java中的LDAP获取AD组的所有成员

时间:2017-06-22 23:19:56

标签: java active-directory ldap

我编写了一个应用程序,它检索Active Directory组并展平它们,即包括递归的子组成员到顶层父组。 它适用于小团体,但对于较大的团体,我遇到了问题。

如果成员数不超过1500,则会在成员属性中列出。如果还有更多 - 则此属性为空,并显示名称为成员;范围:0-1499 的属性,其中包含前1500个成员。

我的问题是我不知道如何让其他成员设置超过1500。 我们有8-12万名会员。我需要运行另一个查询吗? 在微软网站上,我看到了类似问题的C#代码片段,但对它没有多大意义,因为它们展示了如何指定范围,而不是如何将其插入查询。如果有人知道如何用Java做,我会很感激。

3 个答案:

答案 0 :(得分:1)

这显然会给你下一个:

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

您需要按块(1500块)获取用户块只需创建一个计数器并更新您的搜索并检索下一个,直到您拥有所有这些块。

答案 1 :(得分:1)

在您的帮助下,我有完整的工作代码

    // Initialize
    LdapContext ldapContext = null;
    NamingEnumeration<SearchResult> results = null;
    NamingEnumeration<?> members = null;

    try {
        // Initialize properties
        Properties properties = new Properties();
        properties.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        properties.put(Context.PROVIDER_URL, "ldap://" + ldapUrl);
        properties.put(Context.SECURITY_PRINCIPAL, adminLoginADOnPremise);
        properties.put(Context.SECURITY_CREDENTIALS, adminPasswordADOnPremise);

        // Initialize ldap context
        ldapContext = new InitialLdapContext(properties, null);

        int range = 0;
        boolean finish = false;
        while (finish != true) {
            // Set search controls
            SearchControls searchCtls = new SearchControls();
            searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            searchCtls.setReturningAttributes(generateRangeArray(range));

            // Get results
            results = ldapContext.search(ldapBaseDn, String.format("(samAccountName=%s)", groupName), searchCtls);
            if (results.hasMoreElements() == true) {
                SearchResult result = results.next();
                try {
                    members = result.getAttributes().get(generateRangeString(range)).getAll();
                    while (members.hasMore()) {
                        String distinguishedName = (String) members.next();
                        logger.debug(distinguishedName);
                    }
                    range++;
                } catch (Exception e) {
                    // Fails means there is no more result
                    finish = true;
                }
            }
        }
    } catch (NamingException e) {
        logger.error(e.getMessage());
        throw new Exception(e.getMessage());
    } finally {
        if (ldapContext != null) {
            ldapContext.close();
        }
        if (results != null) {
            results.close();
        }
    }

答案 2 :(得分:1)

@Nicolas的工作代码示例中缺少两个函数,我想它们应该是这样的:

public static String[] generateRangeArray(int i) {
    String range = "member;range=" + i * 1500 + "-" + ((i + 1) * 1500 - 1);
    String[] returnedAtts = { range };

    return returnedAtts;
}

public static String generateRangeString(int i) {
    String range = "member;range=" + i * 1500 + "-" + ((i + 1) * 1500 - 1);

    return range;
}

如果AD组的大小不大,以至于实际上需要对“成员”属性进行分块(即存在“成员”属性),则该代码将无法处理这种情况。