【问题标题】:Get user information from DN从 DN 获取用户信息
【发布时间】:2012-06-16 23:36:50
【问题描述】:

下面的代码我有两个目标

1) 获取属于特定广告组的用户列表
2) 获取属于该组的所有用户的电子邮件/姓氏/名字

如果有更好的方法来实现这两者,请告诉我。

我能够获取完整的 DN,但我不确定如何从完整的 DN 中获取剩余数据,或者如果有更好的方法来获取此信息,请告诉我。以下是我正在使用的代码,但出现错误:

The value provided for adsObject does not implement IADs.

当我尝试使用完整的 DN 执行 DirectorySearcher 时。

HashSet<string> User_Collection = new HashSet<string>();

SearchResultCollection sResults = null;
DirectoryEntry dEntryhighlevel = new DirectoryEntry("LDAP://CN=Global_Users,OU=Astrix,OU=Clients,OU=Channel,DC=astro,DC=net");
foreach (object dn in dEntryhighlevel.Properties["member"])
{
    DirectoryEntry dEntry = new DirectoryEntry(dn);
    Console.WriteLine(dn);
    DirectorySearcher dSearcher = new DirectorySearcher(dEntry);
    //filter just user objects
    dSearcher.SearchScope = SearchScope.Base;
    //dSearcher.Filter = "(&(objectClass=user)(dn="+dn+")";
    dSearcher.PageSize = 1000;
    sResults = dSearcher.FindAll();
    foreach (SearchResult sResult in sResults)
    {
        string Last_Name = sResult.Properties["sn"][0].ToString();
        string First_Name = sResult.Properties["givenname"][0].ToString();
        string Email_Address = sResult.Properties["mail"][0].ToString();
        User_Collection.Add(Last_Name + "|" + First_Name + "|" + Email_Address);
    }

速度很重要,是的,我知道我没有按照设计使用 HashSet。

【问题讨论】:

    标签: c# active-directory


    【解决方案1】:

    我总是使用System.DirectoryServices.AccountManagement

    您将看到的第一件事是:“在可用时,使用快速并发绑定 (FSB) 功能可以提高连接速度。连接缓存会减少使用的端口数量。” 话虽如此,我没有针对速度测试你的代码,你必须自己做,但这是微软的新库。

    这是我的代码示例:

    // Create the context for the principal object. 
    PrincipalContext ctx = new PrincipalContext(ContextType.Domain,
                                                "fabrikam",
                                                "DC=fabrikam,DC=com");
    
    // Create an in-memory user object to use as the query example.
    GroupPrincipal u = new GroupPrincipal(ctx) {DisplayName = "Your Group Name Here"};
    
    // Set properties on the user principal object.
    
    // Create a PrincipalSearcher object to perform the search.
    PrincipalSearcher ps = new PrincipalSearcher {QueryFilter = u};
    
    // Tell the PrincipalSearcher what to search for.
    
    // Run the query. The query locates users 
    // that match the supplied user principal object. 
    PrincipalSearchResult<Principal> results = ps.FindAll();
    
    foreach (UserPrincipal principal in ((GroupPrincipal)results.FirstOrDefault()).Members)
    {
        string email = principal.EmailAddress;
        string name = principal.Name;
        string surname = principal.Surname;
    }
    

    【讨论】:

      【解决方案2】:

      看起来您正在 AD 中某个组的组成员身份...(从上面的成员参考中猜测)

      无论如何,您需要确定您要查找的 API 类型。您现在使用的级别较低(尽管您可以根据需要降低 :))。正如前面的答案所没有的那样,提高水平是一种选择。

      进一步修改代码(并帮助提高性能,正如您提到的那样,它对您很重要):

      • 使用与组成员搜索本身相同的连接(即没有额外的连接/绑定)
      • 进行基本搜索,其中基本 DN 是用户 DN,搜索过滤器是 (objectclass=*),并且属性只有您关心的属性(无 *)
      • 您可以删除页面大小。分页是一种在组(也称为页面)中请求多个对象的方法,但基本搜索仅返回 1 个对象,因此它实际上并没有做任何事情。
      • 基本搜索结果计数应始终为 1。

      也要注意跨域问题。确保您使用 2 域森林测试您的代码,其中 domain1 中的一组类型域 local 在其中包含来自域 2 的成员。这将产生一些额外的工作来获取更多属性,因为您需要连接到另一个中的 DC域(如果您关心的少数属性都在 GC 部分属性集中,则为 GC...)

      还要注意安全性。如果您对域中的某些用户无权访问这些属性,那么代码会做什么?上面的代码会以令人讨厌的方式失败。 :) 你可能想更优雅地处理这个......

      希望这会有所帮助。 ~埃里克

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-09
        • 2015-09-22
        • 1970-01-01
        • 2022-01-10
        • 2013-12-08
        • 2011-05-13
        相关资源
        最近更新 更多