【问题标题】:How to get all members of AD group via LDAP in Java如何在 Java 中通过 LDAP 获取 AD 组的所有成员
【发布时间】:2017-06-22 23:19:56
【问题描述】:

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

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

我的问题是我不知道如何让其余的成员设置超过 1500。 我们有 8-12,000 名成员的团体。我需要运行另一个查询吗? 在 Microsoft 网站上,我在类似的问题上看到了 C# 代码 sn-p,但无法理解它,因为他们展示了如何指定范围,而不是如何将其插入查询。如果有人知道如何用 Java 做到这一点,我将不胜感激。

【问题讨论】:

标签: java active-directory ldap


【解决方案1】:

这显然会给你下一个:

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

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

【讨论】:

  • 谢谢,几周前我也遇到过同样的事情。
  • 生成范围的小函数如下所示: public String[] genRange(int i) { String range = "member;range=" + i * 1500 + "-" + ( (i + 1) * 1500 - 1); String[] 返回Atts = { range };返回返回的Atts; }
【解决方案2】:

在你的帮助下,我有一个完整的工作代码

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

【讨论】:

  • 您没有包含 generateRangeString(range) 的代码
  • 嗨 Nicolas,你能告诉我什么是“ldapBaseDn”
【解决方案3】:

@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组没有太大以至于实际上需要“分块”成员属性,即如果“成员”属性存在,则代码不处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多