【问题标题】:How can I filter users by group membership across multiple OU's?如何跨多个 OU 按组成员身份筛选用户?
【发布时间】:2013-04-04 00:58:29
【问题描述】:

我有一个无法在 OU 级别完成的用户查询。我试图只返回他们是组成员的用户(我需要按组字符串值过滤,而不是实际的组对象)。这是它目前的样子:

using (var entry = new DirectoryEntry("LDAP://foo.net/DC=appName,DC=domainName,DC=com", Username, Password)) {
    using (var searcher = new DirectorySearcher()) {
        searcher.Filter = "(&(objectClass=user))";
        searcher.SearchRoot = entry;
        searcher.PropertiesToLoad.Add("memberOf");

        foreach (SearchResult sr in searcher.FindAll()) {
            var member = GetSearchResultProperty(sr, "memberOf");
        }
    }
}

此查询跨越多个 OU,其中有不同的用户和组容器。

当我执行查询(不指定任何类型的 OU)时,我是否可以过滤 memberOf 属性?

【问题讨论】:

    标签: c# active-directory ldap directoryservices


    【解决方案1】:

    只需在过滤器中添加另一个术语:

    searcher.Filter = "(&(objectClass=user)(memberOf=myGroup))";
    

    【讨论】:

    • 这不起作用。我相信memberOf 可能需要完整的组对象路径而不仅仅是名称。如果我只使用 user 过滤器,我会返回多个 OU 中的所有用户。但是,一旦我按照上面的建议将组的名称添加到过滤器中,我就没有得到任何结果。这是显示来自 AD 资源管理器的组成员身份的字符串:CN=myGroup,CN=groups,OU=theOU,DC=appName,DC=domainName,DC=com
    【解决方案2】:

    在执行查询时,我尝试执行的操作似乎是不可能的,因为 memberOf 属性需要是组的完整路径。在我的例子中,我实际上并不关心组对象,而是组名(每个 OU 将有不同的组,但可以有相同的组名)。我不得不采取不同的方法来解决这个问题,这可能会对以后的性能产生影响。以防万一其他人发现这个问题正在寻找答案,我现在是这样解决的:

    using (var entry = new DirectoryEntry("LDAP://foo.net/DC=appName,DC=domainName,DC=com", Username, Password)) {
        using (var searcher = new DirectorySearcher()) {
            searcher.Filter = "(&(objectClass=user))";
            searcher.SearchRoot = entry;
            searcher.PageSize = 5000;
            searcher.PropertiesToLoad.Add(DirectoryConstants.AD_PROPERTY_MEMBER_OF);
            searcher.PropertiesToLoad.Add(DirectoryConstants.AD_PROPERTY_DISPLAY_NAME);
    
            foreach (SearchResult sr in searcher.FindAll()) {
                //The memberOf property will be a string array if the user is in multiple groups.
                string[] memberOf = GetSearchResultProperties(sr, DirectoryConstants.AD_PROPERTY_MEMBER_OF);
                //Check if the user is in the group by analyzing the string.
                var group = memberOf.FirstOrDefault(m => m.StartsWith(string.Format("CN={0},", groupName)));
    
                if (group != null) {
                    //The user is in the group!
                }
            }
        }
    }
    

    【讨论】:

    【解决方案3】:

    您需要在搜索过滤器中包含组的完整可分辨名称,因为 memberOf 属性将包含该值。

    searcher.Filter = "(&(objectClass=user)(memberOf=CN=myGroup,CN=groups,OU=theOU,DC=appName,DC=domainName,DC=com))";
    

    编辑:

    抱歉,我误读了这个问题。在不包括 OU 的情况下,唯一的其他方法是采取相反的方法,并首先定位组对象:

    searcher.Filter = "(&(objectClass=group)(name=Your Group Name)"
    

    然后使用 DirectoryEntry 的属性遍历它:

    foreach(object dn in group.Properties["member"] )
    {
        string DistinguishedName = dn.ToString();
    }
    

    如果您要检索超过 1,000 名以上的用户,则需要采用更加细分的方法,详细信息 in this article

    【讨论】:

    • 在我的原始帖子中,我说我无法在 OU 级别执行搜索,因此,看起来无法按照我想要的方式过滤组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-03-22
    • 1970-01-01
    • 2013-03-04
    • 1970-01-01
    • 2010-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多