【问题标题】:Find user's member of groups in Microsoft AD inside Domain Users security group在域用户安全组内的 Microsoft AD 中查找用户的组成员
【发布时间】:2019-10-09 07:57:56
【问题描述】:

我需要使用 Domain Users 组内的 java 在 Microsoft Active Directory 中查找给定用户的组成员。我的广告结构如下。

reg1.subdomain.domain.com - 用户(类型 - 容器) - 域用户(类型 - 安全组全局)

我写了下面的代码。但我无法查询域用户组内的用户。

public static String ldapUri = "ldap://ldapuri.com:389";
    public static String usersContainer = "CN=users,DC=reg1,DC=subdomain,DC=domain,DC=com";
    public ArrayList<String> getUserGroups(String username, String password){
        Hashtable env = new Hashtable();
        env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");
        env.put(Context.PROVIDER_URL, ldapUri);
        env.put(Context.SECURITY_PRINCIPAL, username);
        env.put(Context.SECURITY_CREDENTIALS, password);
        try {
            DirContext ctx = new InitialDirContext(env);
            SearchControls ctls = new SearchControls();
            String[] attrIDs = { "memberOf" };
            ctls.setReturningAttributes(attrIDs);
            ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);

            NamingEnumeration answer = ctx.search(usersContainer, "(&(objectCategory=group)(cn=Domain Users)(sAMAccountName=username))", ctls);
            while (answer.hasMore()) {
                SearchResult rslt = (SearchResult) answer.next();
                Attributes attrs = rslt.getAttributes();
                try{
                    String groups = attrs.get("memberOf").toString();
                    String [] groupname = groups.split(":");
                    System.out.println(groupname[1]);
                }catch (Exception e){
                    System.out.println("no members");
                }
            }
            ctx.close();
        } catch (NamingException e) {
            e.printStackTrace();
        }
        return list;
    }

谁能指出我添加的过滤查询有什么问题?

【问题讨论】:

    标签: java active-directory ldap ldap-query


    【解决方案1】:

    Domain Users group 是一个全局组安全组,默认情况下包含域中的所有用户帐户。当您在域中创建用户帐户时,默认将其添加到该组中。

    大多数方法不会显示“主要”组的成员身份。对于大多数用户,“主要”组将是“域用户”。具体来说,用户对象的 memberOf 属性和组对象的 member 属性永远不会显示“主要”组成员身份。在大多数域中,“域用户”组的成员属性为空,可以安全地假设所有用户都属于该组。

    域用户 LDAP 查询示例对于将“域用户”指定为其“主要”的所有用户,搜索所有 primaryGroupID 属性为 513(默认情况下)的用户。 “域用户”组的 primaryGroupID 属性是相同的整数,513。LDAP 语法 LDAP SearchFilter 可以是:

    (primaryGroupID=513)
    

    这假定您没有更改默认值,也没有创建任何具有非 513 的 primaryGroupID 的用户。

    对于“域用户”组中的用户,只需使用 (primaryGroupID=513) 和用户所在的 baseDN(默认为 CN=Users),这将返回用户的 DN。

    然后,要获取这些用户所属的所有组,您需要在另一个查询中使用 DN 循环遍历结果,类似于:

    (member:1.2.840.113556.1.4.1941:=(CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))
    

    如图All Groups a User is a member of including Nested Groups

    哦,通常情况下,CN=Users 中的用户也通常与伪组“域用户”中的成员相同。

    【讨论】:

    • 这是正确的。我在一篇关于 What makes a member a member 的文章中写到了这一点,其中包含有关该数字含义的一些细节。
    • 好的。我将过滤器更改为 NamingEnumeration answer = ctx.search(usersContainer, "(&(objectCategory=person)(primaryGroupID=513)(sAMAccountName=username))", ctls);现在如果给我用户 CN 中的用户而不是域用户安全组。如果让用户进入域用户安全组,我需要知道什么
    • 对于“域用户”组中的用户,只需使用 (primaryGroupID=513) 和用户所在的 baseDN(默认为 CN=Users),这将返回用户的 DN。
    【解决方案2】:

    假设基础usersContainer 设置正确,您只需按如下方式更改过滤器:

    • 搜索 user 条目时,您需要修复 objectCategory 以过滤用户 - 而不是组。你也可以使用类似objectClass=inetOrgPerson的等价物。

    • 除非您正在搜索的用户条目确实具有属性cn=Domain Users(这不太可能作为用户的通用名),否则您不需要这部分。

    所以以下内容就足够了:

    ctx.search(usersContainer, "(&(objectCategory=person)(sAMAccountName=username))", ctls);
    

    要匹配特定的用户组成员资格,您只需在memberOf 属性上添加过滤器(仅当用户是给定组的成员时才返回匹配的用户条目),例如。 :

    (&(objectCategory=person)(sAMAccountName=username)(memberOf=<groupDN>))
    

    注意,正如@jwilleke 所说,如果您针对不维护会员属性的特殊群组(group:member/user:memberOf),您需要使用primaryGroupID 而不是memberOf

    也就是说,由于sAMAccountName 在域内的所有安全主体对象中是唯一的,因此您可能只需要使用UserPrincipalName 而不是添加过滤器:

    (&(objectCategory=person)(UserPrincipalName=username@domain.com))
    

    【讨论】:

    • 我需要获取域用户安全组中给定用户名的用户“成员”中的所有组
    • 这恰恰是关于检索用户所属的组,这意味着:搜索给定用户名的用户条目并获取其 memberOf 属性。条件“用户必须是给定组的成员”已解决 -> 添加相应的过滤器。正如@jwilleke 所说,如果您针对不维护会员属性的特殊群体(group:member/user:memberOf),您需要使用primaryGroupID 而不是memberOf
    • 也就是说,你真的需要它吗?我的意思是sAMAccountName 在域内的所有安全主体对象中必须是唯一的,那么您也有UserPrincipalName
    【解决方案3】:

    上面给出的代码 sn-p 是正确的,除了我指定的搜索方法。我无法从用户容器中搜索域用户组内的用户,因为我没有提到在子目录中搜索。通过添加搜索范围,

    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    

    能够成功找回用户

    【讨论】:

    • 除了您使用的过滤器(&amp;(objectCategory=group)(cn=Domain Users)(sAMAccountName=username)),它不能返回任何用户条目。或者,也许您可​​以解释 objectCategory=group 如何最终匹配用户 (objectCategory=Person) ?是范围吗?
    猜你喜欢
    • 2021-05-01
    • 2014-03-18
    • 2023-04-11
    • 1970-01-01
    • 2010-10-14
    • 2021-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多