使用Java

时间:2019-07-25 11:31:53

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

我的要求是,基于用户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();
    }
}

}

1 个答案:

答案 0 :(得分:0)

全局编录的工作方式与普通LDAP连接相同,但是它只是从其他端口运行。因此,您只需要指定3268的GC端口即可:

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

就是这样。

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

您将必须知道12个域的组织方式。您将必须对每个AD林进行一次搜索。您无法进行一次搜索来在不同的林中找到帐户。

还有其他警告,例如某些AD属性未复制到全局目录中。例如,您要寻找的accountExpires属性不会复制到GC。如果您look up the attribute on the Microsoft site,您会看到“在全球目录中”是“假”。