【问题标题】:Fetch the user details from LDAP Active directory from MULTIPLE domains using Java使用 Java 从多个域的 LDAP 活动目录中获取用户详细信息
【发布时间】:2019-12-03 16:10:01
【问题描述】:

我的要求是,根据用户 ID,我需要从 LDAP 活动目录中获取用户详细信息(如名字和姓氏)。 但是这里的问题是我们不知道哪个域用户将存在。我们有大约 12 个不同的域,每个域都有不同的提供者 URL。 目前,当我提供输入时,我能够从一个域中获取用户详细信息 - 1. providerURL(这是特定于域的,每个域都有不同的 URL) 2.用户名 3.密码

由于问题是我们不知道哪个域用户将存在,我不想在每个域中进行顺序或并行调用来逐个搜索用户。 有没有其他方法可以在一次通话中搜索所有可用域中的特定用户? 寻找任何简单的基于 Java 或基于 spring-java 的解决方案。

我们听说 LDAP 活动目录中有全局 Catlog,但不太了解。如果我们创建一些全局帐户(将充当超级用户)然后使用该全局帐户详细信息,我们是否可以在所有域中搜索特定用户。

我不知道 LDAP 活动目录服务器结构,如果可以的话 服务帐户(具有特殊角色访问权限),以便使用它我可以在所有域中搜索用户详细信息。

另一个查询是 -> 而不是全局服务帐户,如果我们在一个域中创建一个具有一些额外特殊角色访问权限的服务帐户,那么我可以使用它来搜索来自任何其他域的用户吗?

请针对我们的项目需求提出解决方案。

目前我可以使用以下代码从一个域中获取用户详细信息->

公共类 LDAPExaminer {

public static void main(String[] args) {
    LDAPExaminer ldapExaminer = new LDAPExaminer();

    ldapExaminer.printUserBasicAttributes("userId", ldapExaminer.getLdapContext());
}

public LdapContext getLdapContext() {
    LdapContext ctx = null;
    try {
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.SECURITY_AUTHENTICATION, "Simple");


        env.put(Context.SECURITY_PRINCIPAL, "user@domain");

        env.put(Context.SECURITY_CREDENTIALS, "password");

        env.put(Context.PROVIDER_URL, "ldap://example.domain.com");

        env.put(Context.REFERRAL, "follow");
        System.out.println("Attempting to Connect...");

        ctx = new InitialLdapContext(env, null);
        System.out.println("Connection Successful.");
    } catch (NamingException nex) {
        System.out.println("LDAP Connection: FAILED");
        nex.printStackTrace();
    }
    return ctx;
}

private void printUserBasicAttributes(String username, LdapContext ctx) {
    try {

        SearchControls constraints = new SearchControls();
        constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);

        String[] attrIDs = {"distinguishedName", "UN", "givenname", "mail", "telephonenumber", "canonicalName", "userAccountControl", "accountExpires"};
        constraints.setReturningAttributes(attrIDs);


        NamingEnumeration answer = ctx.search("DC=example,DC=domain,DC=com", "sAMAccountName=" + username, constraints);

        if (answer.hasMore()) {
            Attributes attrs = ((SearchResult) answer.next()).getAttributes();
            System.out.println(attrs.get("distinguishedName"));
            System.out.println(attrs.get("givenname"));
            System.out.println(attrs.get("sn"));
            System.out.println(attrs.get("mail"));
            System.out.println(attrs.get("telephonenumber"));
            System.out.println(attrs.get("canonicalName"));
            System.out.println(attrs.get("userAccountControl"));
            System.out.println(attrs.get("accountExpires"));
        } else {
            throw new Exception("Invalid User");
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
}

}

【问题讨论】:

标签: active-directory ldap spring-ldap ldap-query active-directory-group


【解决方案1】:

全局目录的工作方式与普通 LDAP 连接相同,但它只是从不同的端口运行。所以只需要指定 3268 的 GC 端口即可:

env.put(Context.PROVIDER_URL, "ldap://example.domain.com:3268");

就是这样。

GC 将让您找到同一 AD 林中的所有帐户,这是一组相互完全信任的域。一个域上的帐户可以在另一个域上进行身份验证,并且可以轻松地在它们之间授予权限。

您必须知道您的 12 个域是如何组织的。您必须对每个 AD 林进行一次搜索。您无法进行一次搜索即可在不同的森林中找到帐户。

还有其他注意事项,例如某些 AD 属性不会复制到全局目录中。例如,您正在查找的 accountExpires 属性不会复制到 GC。如果你look up the attribute on the Microsoft site,你会看到“In Global Catalog”是“False”。

【讨论】:

  • 已经尝试使用端口 3268 ,但无法从其他域获取。似乎 AD 森林在我们的组织中是独立的。
  • 如果它们在不同的森林中,那么您别无选择,只能分别查询它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多