【问题标题】:How can i programmatically get the root of an Active Directory Forest via C#如何通过 C# 以编程方式获取 Active Directory 林的根
【发布时间】:2016-11-10 06:39:52
【问题描述】:

我的客户拥有庞大的 Active Directory 目录。例如:

company.com
  de.company.com
  us.company.com
  in.company.com
  xx.company.com

当我得到当前用户时,我得到domainname\username。当我获取域名并想在此域中搜索世界上的其他用户时,我无法导致我需要知道 company.com 来进行目录搜索。

在 C# 中有没有办法获取我使用 DirectorySearcher 或任何其他 C# 方法来查询 AD 的根对象?

【问题讨论】:

  • 您是否尝试过使用专有名称?
  • 杰出的名字?

标签: c# active-directory directoryservices


【解决方案1】:

根目录林名称可以从 RootDSE 分区获取。查看 rootDomainNamingContext 属性。这将返回您的森林根域。我不建议从用户 DN 中提取森林名称,因为如果您在一个森林中有 2 棵域树,它将不起作用。第二个选项是在当前域的全局目录中搜索用户。全局目录包含整个林中所有用户的部分副本

下面的代码对全局编录执行搜索。我在我的森林中有 2 个域,因此它返回了 2 个用户。请注意,您将不得不处理返回的多个结果:

        var forest = Forest.GetCurrentForest();
        var globalCatalog = GlobalCatalog.FindOne(new DirectoryContext(DirectoryContextType.Forest, forest.Name));

        using (var connection = new LdapConnection(new LdapDirectoryIdentifier(globalCatalog.Name, 3268)))
        {
            var entries = new List<SearchResultEntry>();

            var searchRequest = new SearchRequest(string.Empty, "(samaccountname=administrator)", SearchScope.Subtree, null);
            var searchOptionsControl = new SearchOptionsControl(System.DirectoryServices.Protocols.SearchOption.DomainScope);

            searchRequest.Controls.Add(searchOptionsControl);

            var pageResultRequestControl = new PageResultRequestControl(1000);

            searchRequest.Controls.Add(pageResultRequestControl);

            do
            {
                var response = (SearchResponse)connection.SendRequest(searchRequest);

                if (response != null)
                {
                    if (response.ResultCode != ResultCode.Success)
                    {
                        throw new ActiveDirectoryOperationException(response.ErrorMessage, (int) response.ResultCode);
                    }

                    foreach (var c in response.Controls.OfType<PageResultResponseControl>())
                    {
                        pageResultRequestControl.Cookie = c.Cookie;
                        break;
                    }

                    entries.AddRange(response.Entries.Cast<SearchResultEntry>());
                }
            }
            while (pageResultRequestControl.Cookie != null && pageResultRequestControl.Cookie.Length > 0);
        }

关于此代码的几点说明: 1.当然,这段代码不是生产代码。您可以编写更通用的 LdapSearcher,例如可以找到一个 here。如果需要,您可以制作此搜索器的同步版本。 2. 我强烈建议在基于服务的应用程序中使用 LdapConnection 而不是 DirectorySearcher,因为在企业环境中使用 DirectorySearcher 会导致内存泄漏和其他issues

【讨论】:

  • 嗯,好的,我将尝试使用 rootDomainNamingContext。这听起来不错,网络上的示例是透明的/可以理解的,也许是我正在寻找的东西,但是您能否提供更多关于全球目录的信息?
  • 全局编录是一个域控制器,它存储所有林对象的特定属性。对于每个属性,Active Directory 架构指定该属性是否存储在全局编录中。您可以查看 System.DirectoryServices.ActiveDirectory.Forest 类,它为您提供所有可用全局目录的信息。如果您不知道搜索用户所属的域名,则此方法适用。要查询全局目录,您需要指定 GC:// 而不是 LDAP://
  • 如果全局目录中没有搜索到的属性,您仍然可以创建 Forest 类,然后从该类中获取 Forest 域列表并在每个域中搜索用户
  • 如果您向我提供有关如何搜索用户的更多详细信息,我。 e.根据您要从 AD 查询的属性和信息,我可以给您更具体的建议
  • 给出:姓名或姓氏或amaccountname或电子邮件地址。因为我正在根据上述信息之一搜索用户,我没有域名。它是一个 ASP.NET MVC 应用程序,它在带有 IIS 的 Windows 服务器上运行,并且服务器已加入域。我还有一个经典的 WinForms 解决方案,我有完全相同的要求。桌面应用程序在也连接到域的用户客户端上运行。我需要使用户能够根据上面的过滤信息搜索用户/用户。如果您对我有具体的建议,那就太好了。
【解决方案2】:

要获取用户的根对象,请使用属性或属性distinguished name 来确定活动目录中的完全限定路径。从右侧读取结构并提取根元素。

E. G。 cn=John Doe, ou=People, dc=sun.com

【讨论】:

  • 但是如果你有类似dc=de,dc=eu,dc=company,dc=com (de.eu.company.com) 的东西并且你只需要root dc=company,dc=com (company.com) 怎么办?
  • @STORM 只需读取当前用户的专有名称和RegExSplitSubstring 的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多