查找属于两个活动目录组的用户

时间:2011-06-23 16:48:56

标签: c# .net active-directory

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

我知道使用memberOf进行ldap搜索不会考虑嵌套组。我还可以专门找到这两个组,获取成员列表,并迭代它们,匹配作为两个列表成员的那些,但组的成员集合也不考虑嵌套组。是否有任何方法可以使用嵌套组,或者我是否需要编写自己的递归逻辑?

修改 嵌套组:如果我有一个名为GroupA的安全组。 GroupA可以拥有用户或其他组的成员。如果GroupB是GroupA的成员,GroupB就是我所谓的“嵌套组”。

3 个答案:

答案 0 :(得分:2)

这是在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();
}

答案 1 :(得分:0)

除了通过递归,我不知道有什么方法可以做到这一点。获取组a的组成员资格。循环遍历列表,如果item是用户添加到第二个列表,如果item是一个组然后执行递归。

答案 2 :(得分:0)

是否要求您使用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();