【问题标题】:Finding users that are members of two active directory groups查找属于两个 Active Directory 组的用户
【发布时间】:2011-06-23 16:48:55
【问题描述】:

我需要找到属于两个组(GroupA 和 GroupB)的所有用户。我还需要考虑嵌套组。最好的方法是什么?

我知道使用 memberOf 进行 ldap 搜索不会考虑嵌套组。我还可以专门定位这两个组,获取成员列表,然后遍历它们,匹配两个列表中的成员,但是组的成员集合也不考虑嵌套组。有没有适用于嵌套组的方法,还是我需要编写自己的递归逻辑?

编辑 嵌套组:如果我有一个名为 GroupA 的安全组。 GroupA 可以具有用户或其他组的成员。如果 GroupB 是 GroupA 的成员,我称之为“嵌套组”。

【问题讨论】:

  • 请定义“嵌套组”。
  • 抱歉,“嵌套组”可能是我自己的术语,所以我添加了对它的描述......
  • 这与我未回答的问题stackoverflow.com/questions/4430567/… 非常相似

标签: c# .net active-directory


【解决方案1】:

这是在 ActiveDirectory 2003 和 2008 R2 中工作的东西。我使用Microsoft LDAP_MATCHING_RULE_IN_CHAIN 来:

1) 递归搜索(但在一个查询中)来自第一个组的所有用户(小心它返回来自安全和分发组的用户)

2) 对于第一个查询中的每个用户,如果用户属于第二个组,我会再次递归搜索(但在一个查询中)。

static void Main(string[] args)
{
  //Connection to Active Directory
  string sFromWhere = "LDAP://SRVENTR2:389/dc=societe,dc=fr";
  DirectoryEntry deBase = new DirectoryEntry(sFromWhere, "societe\\administrateur", "test.2011");

  // To find all the users member of groups "Grp1"  :
  // Set the base to the groups container DN; for example root DN (dc=societe,dc=fr) 
  // Set the scope to subtree
  // Use the following filter :
  // (member:1.2.840.113556.1.4.1941:=CN=Grp1,OU=MonOu,DC=X)
  //
  DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
  dsLookFor.Filter = "(&(memberof:1.2.840.113556.1.4.1941:=CN=Grp1,OU=MonOu,DC=societe,DC=fr)(objectCategory=user))";
  dsLookFor.SearchScope = SearchScope.Subtree;
  dsLookFor.PropertiesToLoad.Add("cn");

  SearchResultCollection srcUsers = dsLookFor.FindAll();

  // Just to know if user is present in an other group
  foreach (SearchResult srcUser in srcUsers)
  {
    Console.WriteLine("{0}", srcUser.Path);

    // To check if a user "user1" is a member of group "group1".
    // Set the base to the user DN (cn=user1, cn=users, dc=x)
    // Set the scope to base
    // Use the following filter :
    // (memberof:1.2.840.113556.1.4.1941:=(cn=Group1,OU=groupsOU,DC=x))
    DirectoryEntry deBaseUsr = new DirectoryEntry(srcUser.Path, "societe\\administrateur", "test.2011");
    DirectorySearcher dsVerify = new DirectorySearcher(deBaseUsr);
    dsVerify.Filter = "(memberof:1.2.840.113556.1.4.1941:=CN=Grp3,OU=MonOu,DC=societe,DC=fr)";
    dsVerify.SearchScope = SearchScope.Base;
    dsVerify.PropertiesToLoad.Add("cn");

    SearchResult srcTheUser = dsVerify.FindOne();

    if (srcTheUser != null)
    {
      Console.WriteLine("Bingo {0}", srcTheUser.Path);
    }
  }
  Console.ReadLine();
}

【讨论】:

    【解决方案2】:

    除了递归之外,我不知道有任何方法可以做到这一点。获取组 a 的组成员身份。遍历列表,如果项目是用户添加到第二个列表,如果项目是组则执行递归。

    【讨论】:

      【解决方案3】:

      您是否需要使用 ldap 搜索来执行此操作? WindowsPrincipal.IsInRole() 方法将直接和通过嵌套组测试成员资格 - 至少在我运行的测试中是这样。

      此代码针对 GroupA 和 GroupB 测试当前线程的身份,但您可以使用类似的方法来枚举 GroupA 的成员,然后通过调用 IsInRole 来针对 GroupB 测试每个成员...

      AppDomain myDomain = Thread.GetDomain();
      
      myDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
      
      WindowsPrincipal myPrincipal = (WindowsPrincipal)Thread.CurrentPrincipal;
      
      NTAccount groupA = new NTAccount("Domain\\GroupA");
      
      SecurityIdentifier sidGroupA = (SecurityIdentifier)groupA.Translate(typeof(SecurityIdentifier));
      
      bool inGroupA = myPrincipal.IsInRole(sidGroupA);
      
      NTAccount groupB = new NTAccount("Domain\\GroupB");
      
      SecurityIdentifier sidGroupB = (SecurityIdentifier)groupB.Translate(typeof(SecurityIdentifier));
      
      bool inGroupB = myPrincipal.IsInRole(sidGroupB);
      
      Console.WriteLine("{0}, {1}", groupA, inGroupA);
      
      Console.WriteLine("{0}, {1}", groupB, inGroupB);
      
      Console.ReadLine();
      

      【讨论】:

      • 我认为这不适用于我的情况,因为我对当前用户是否同时属于这两个组不感兴趣,我有兴趣测试当前用户是否选择了任何选定的帐户在两个组中。
      • 不要过于关注示例代码,这只是为了让您快速检查代码是否与我认为的 GroupA 和 GroupB 的功能相同。在您的情况下,您将枚举组 A(或组 B)的成员,为每个用户创建一个 Windows 主体,然后针对组 B(或组 A,如果您最初枚举组 B)调用 principal.IsInRole。您知道有问题的委托人是您列举的组的成员。 IsInRole 调用将告诉您它是否在另一个组中,并告诉您您想知道什么。
      猜你喜欢
      • 1970-01-01
      • 2011-01-12
      • 2014-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      相关资源
      最近更新 更多