使用 C# 查找递归组成员身份(Active Directory)

时间:2022-11-10
本文介绍了使用 C# 查找递归组成员身份(Active Directory)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我希望获取用户在 Active Directory 中所属的所有组的列表,它们都显式地列在 memberOf 属性列表中,以及通过嵌套的组成员身份隐式列出.例如,如果我检查 UserA 并且 UserA 是 GroupA 和 GroupB 的一部分,如果 GroupB 是 GroupC 的成员,我还想列出 GroupC.

I am looking to get a list of all of the groups that a user is a member of in Active Directory, both explicitly listed in the memberOf property list as well as implicitly through nested group membership. For example, if I examine UserA and UserA is a part of GroupA and GroupB, I also want to list GroupC if GroupB is a member of GroupC.

为了让您更深入地了解我的应用程序,我将在有限的基础上进行此操作.基本上,我希望偶尔进行一次安全检查,以列出这些额外的成员资格.我想区分两者,但这应该不难.

To give you a bit more insight into my application, I will be doing this on a limited basis. Basically, I want a security check occasionally that will list these additional memberships. I will want to differentiate the two but that shouldn't be hard.

我的问题是我还没有找到一种有效的方法来使这个查询工作.Active Directory 上的标准文本(This CodeProject Article)展示了一种方法这基本上是一个递归查找.这似乎非常低效.即使在我的小域中,用户也可能拥有 30 多个组成员身份.这意味着一个用户可以调用 30 多次 Active Directory.

My problem is that I have not found an efficient way to make this query work. The standard text on Active Directory (This CodeProject Article) shows a way to do this that is basically a recursive lookup. That seems terribly inefficient. Even in my small domain, a user might have 30+ group memberships. That means 30+ calls to Active Directory for one user.

我查看了以下 LDAP 代码以一次性获取所有 memberOf 条目:

I've looked into the following LDAP code to get all of the memberOf entries at once:

(memberOf:1.2.840.113556.1.4.1941:={0})

其中 {0} 是我的 LDAP 路径(例如:CN=UserA,OU=Users,DC=foo,DC=org).但是,它不返回任何记录.这种方法的缺点是,即使它有效,我也不知道哪个组是显式的,哪个是隐式的.

where {0} would be my LDAP path (ex: CN=UserA,OU=Users,DC=foo,DC=org). However, it does not return any records. The downside of this method, even if it worked, would be that I wouldn't know which group was explicit and which was implicit.

这就是我目前所拥有的.我想知道是否有比 CodeProject 文章更好的方法,如果有,如何实现(实际代码会很棒).我正在使用 .NET 4.0 和 C#.我的 Active Directory 处于 Windows 2008 功能级别(还不是 R2).

That is what I have so far. I would like to know if there is a better way than the CodeProject article and, if so, how that could be accomplished (actual code would be wonderful). I am using .NET 4.0 and C#. My Active Directory is at a Windows 2008 functional level (it isn't R2 yet).

推荐答案

非常感谢这个有趣的问题.

Thirst thanks for this an interesting question.

接下来,只是更正,你说:

Next, just a correction, you say :

我查看了以下 LDAP 代码以一次性获取所有 memberOf 条目:

I've looked into the following LDAP code to get all of the memberOf entries at once:

(memberOf:1.2.840.113556.1.4.1941:={0})

你不让它工作.我记得当我知道它的存在时我让它工作,但它在 LDIFDE.EXE 过滤器中.所以我将它应用到 C# 中的 ADSI,它仍然有效.我从 Microsoft 获取的示例中有太多括号,但它起作用了 (AD 搜索过滤器语法中的来源).

You don't make it work. I remember I make it work when I learnt about its existence, but it was in an LDIFDE.EXE filter. So I apply it to ADSI in C# and it's still working. There were too much parenthesis in the sample I took from Microsoft, but it was working (source in AD Search Filter Syntax).

根据您关于我们不知道用户是否明确属于该组这一事实的评论,我再添加一个请求.我知道这不是很好,但这是我能做到的最好的.

According to your remark concerning the fact that we don't know if a user explicitly belongs to the group I add one more request. I know this is not very good, but it's the best I'am abable to do.

static void Main(string[] args)
{
  /* Connection to Active Directory
   */
  DirectoryEntry deBase = new DirectoryEntry("LDAP://WM2008R2ENT:389/dc=dom,dc=fr");


  /* To find all the groups that "user1" is a member of :
   * Set the base to the groups container DN; for example root DN (dc=dom,dc=fr) 
   * Set the scope to subtree
   * Use the following filter :
   * (member:1.2.840.113556.1.4.1941:=cn=user1,cn=users,DC=x)
   */
  DirectorySearcher dsLookFor = new DirectorySearcher(deBase);
  dsLookFor.Filter = "(member:1.2.840.113556.1.4.1941:=CN=user1 Users,OU=MonOu,DC=dom,DC=fr)";
  dsLookFor.SearchScope = SearchScope.Subtree;
  dsLookFor.PropertiesToLoad.Add("cn");

  SearchResultCollection srcGroups = dsLookFor.FindAll();

  /* Just to know if user is explicitly in group
   */
  foreach (SearchResult srcGroup in srcGroups)
  {
    Console.WriteLine("{0}", srcGroup.Path);

    foreach (string property in srcGroup.Properties.PropertyNames)
    {
      Console.WriteLine("	{0} : {1} ", property, srcGroup.Properties[property][0]);
    }

    DirectoryEntry aGroup = new DirectoryEntry(srcGroup.Path);
    DirectorySearcher dsLookForAMermber = new DirectorySearcher(aGroup);
    dsLookForAMermber.Filter = "(member=CN=user1 Users,OU=MonOu,DC=dom,DC=fr)";
    dsLookForAMermber.SearchScope = SearchScope.Base;
    dsLookForAMermber.PropertiesToLoad.Add("cn");

    SearchResultCollection memberInGroup = dsLookForAMermber.FindAll();
    Console.WriteLine("Find the user {0}", memberInGroup.Count);

  }

  Console.ReadLine();
}

在我的测试树中,这给出了:

In my test tree this give :

LDAP://WM2008R2ENT:389/CN=MonGrpSec,OU=MonOu,DC=dom,DC=fr
adspath : LDAP://WM2008R2ENT:389/CN=MonGrpSec,OU=MonOu,DC=dom,DC=fr
cn : MonGrpSec
Find the user 1

LDAP://WM2008R2ENT:389/CN=MonGrpDis,OU=ForUser1,DC=dom,DC=fr
adspath : LDAP://WM2008R2ENT:389/CN=MonGrpDis,OU=ForUser1,DC=dom,DC=fr
cn : MonGrpDis
Find the user 1

LDAP://WM2008R2ENT:389/CN=MonGrpPlusSec,OU=ForUser1,DC=dom,DC=fr
adspath : LDAP://WM2008R2ENT:389/CN=MonGrpPlusSec,OU=ForUser1,DC=dom,DC=fr
cn : MonGrpPlusSec
Find the user 0

LDAP://WM2008R2ENT:389/CN=MonGrpPlusSecUniv,OU=ForUser1,DC=dom,DC=fr
adspath : LDAP://WM2008R2ENT:389/CN=MonGrpPlusSecUniv,OU=ForUser1,DC=dom,DC=fr
cn : MonGrpPlusSecUniv
Find the user 0

<小时>

(已编辑)1.2.840.113556.1.4.1941"在 W2K3 SP1 中不起作用,它开始与 SP2 一起工作.我认为这与 W2K3 R2 相同.它应该适用于 W2K8.我在这里用 W2K8R2 测试.我很快就能在 W2K8 上对此进行测试.


(edited) '1.2.840.113556.1.4.1941' is not working in W2K3 SP1, it begins to work with SP2. I presume it's the same with W2K3 R2. It's supposed to work on W2K8. I test here with W2K8R2. I'll soon be able to test this on W2K8.

这篇关于使用 C# 查找递归组成员身份(Active Directory)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:为什么当我插入 DateTime null 时,我有“0001-01-01"?在 SQL Server 中? 下一篇:如何以编程方式更改 Active Directory 密码

相关文章

最新文章