获取嵌套在另一个组中的组成员

时间:2014-09-02 09:01:21

标签: c# active-directory

我正在开发一个仅在用户是Active Directory中某些组的成员时才显示特定链接的Intranet。

我正在使用此代码来有效地检查用户是否是组的成员。如果组仅包含用户,则工作正常,但如果组中嵌套了组则不起作用。我需要的是即使特定用户在嵌套组中也能使它工作!

public bool isMember(string user, string group)
{
    string value = "";
    bool isMember = false;

    try
    {
        DirectoryEntry entry = new DirectoryEntry(domain);
        DirectorySearcher mySearcher = new DirectorySearcher(entry);
        mySearcher.Filter = "sAMAccountname=" + user;

        SearchResult mySearchResult;

        mySearchResult = mySearcher.FindOne();

        PropertyValueCollection prop = mySearchResult.GetDirectoryEntry().Properties["memberOf"];

        for (int i = 0; i < prop.Count; i++)
        {
            value = prop[i].ToString();

            string[] groups = value.Split(',');
            foreach (string property in groups)
            {
                if (groups[1] == group)
                {
                    isMember = true;
                    break;
                }
            }
        }
        entry.Close();
        return isMember;
    }
    catch (COMException)
    {
        return false;
    }
}

我该如何做到这一点?

编辑:

我找到了这段代码,它允许我找到一个用户,即使是一个嵌套组。问题是它只有在我的组织单位包含一个组时才有效,如果有多个组则不起作用...你认为我可以编辑它以使其正常工作吗?

public bool isMember(string user, string group)
{
    bool found = false;

    PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domain");
    GroupPrincipal p = GroupPrincipal.FindByIdentity(ctx, IdentityType.Name, group);
    UserPrincipal u = UserPrincipal.FindByIdentity(ctx, user);

    found = p.GetMembers(true).Contains(u);

    p.Dispose();
    u.Dispose();

    return found;
}

从 - &gt; here&lt; -

获取此代码

2 个答案:

答案 0 :(得分:0)

您可以考虑使用tokenGroups向AD申请令牌。查看http://dunnry.com/blog/EnumeratingTokenGroupsTokenGroupsInNET.aspx样本。

答案 1 :(得分:0)

有两种方法可以做到这一点。

  1. 递归检查找到的每个组的memberOf属性。请注意,可能存在循环引用,因此您必须跟踪所访问的组以避免无限递归。

  2. 使用LDAP_MATCHING_RULE_IN_CHAIN规则直接或间接搜索用户所属的所有组。要执行此操作,您需要先获取用户的DN,然后搜索包含该userDN的组作为直接或间接成员。过滤器类似于:

    String.Format("(member:1.2.840.113556.1.4.1941:={0})", userDN)
    
  3. IIRC选项1通常更快,但当然需要更多代码。