【问题标题】:Filter Active Directory users by Company name, Asp.net Core 2.1按公司名称过滤 Active Directory 用户,Asp.net Core 2.1
【发布时间】:2020-01-27 14:56:47
【问题描述】:

问题

我正在寻找一种方法来根据当前登录的用户 Active Directory 公司名称(在 AD 配置文件中找到)从 Active Directory 中过滤用户。

要搜索 AD,我目前正在使用以下代码,它返回包括系统帐户在内的所有用户 -

PrincipalContext context = new PrincipalContext(ContextType.Domain, "mydomain");
var domainUsers = new List<string>();
var userPrincipal = new UserPrincipal(context);

using (var search = new PrincipalSearcher(userPrincipal))
{
    foreach (var user in search.FindAll())
    {
        if (user.DisplayName != null)
        {
            domainUsers.Add(user.DisplayName);
        }
    }
}

我正在寻找一种仅返回与当前 AD 登录用户的公司名称匹配的用户的方法。即,如果公司名称是 Test123,则搜索结果将仅包括属于 Test123 公司的所有其他用户。

背景

我正在开发一个 asp.net MVC 2.1 Web 应用程序,它需要来自活动目录的用户下拉列表。

【问题讨论】:

    标签: c# asp.net asp.net-mvc asp.net-core active-directory


    【解决方案1】:

    在 Active Directory 中搜索所有用户并匹配 company 字段。

    在遍历基于查询找到的所有用户的列表时,您可以将 Principal 转换为 DirectoryEntry,因为 Principal 没有您需要的信息。在过滤方面,DirectoryEntry 具有您可以查找和使用的属性。本例中仅使用“公司”。

        PrincipalContext context = new PrincipalContext(ContextType.Domain, "mydomain");
        var domainUsers = new List<string>();
        var userPrincipal = new UserPrincipal(context);
        string myCompany = "Test123";
        using (var search = new PrincipalSearcher(userPrincipal))
        {
            foreach (Principal user in search.FindAll())
            {
                string usersCompany = ((DirectoryEntry)user.GetUnderlyingObject())?.Properties["company"]?.Value?.ToString();
                if (user.DisplayName != null && usersCompany != null && usersCompany.Equals(myCompany))
                {
                    domainUsers.Add(user.DisplayName);
                }
            }
        }
    

    编辑

    出于性能原因,我建议使用DirectorySearcher 而不是PrincipalSearcher。这是另一个版本。在执行FindAll() 之前完成搜索。

        string myCompany = "Test123";
        string searchQuery = $"(&(objectCategory=user)(objectClass=user)(company={myCompany}))";
    
        // You can define the fields you want retrieved from AD (Noted by @GabrielLuci)
        DirectorySearcher ds = new DirectorySearcher(searchQuery, 
                                   new string[] { "DisplayName" }); 
        foreach(SearchResult user in ds.FindAll())
        {
            domainUsers.Add(user.Properties["DisplayName"][0].ToString());
        }
    

    【讨论】:

    • @bsod_ 查看我对帖子的更新。这比之前的 PrincipalSearcher 效率高很多。
    • +1 更新。使用DirectorySearcher/DirectoryEntry 总是更快。我实际上写了一篇关于这个的文章:Active Directory: Better Performance。您仍然可以改进代码的几种方法是 1. 使用 PropertiesToLoad 只返回您需要的属性,以及 2. 不要使用 GetDirectoryEntry() - 改用 user.Properties["displayName"][0]。我在我的文章中解释了原因。
    • @GabrielLuci 总是乐于接受建议。我确实更喜欢使用属性,并更新了代码以反映这一点。
    • @GabrielLuci 谢谢!我已经用部门代替了公司,效果很好!我们如何添加多个部门? “部门 1 和部门 2”?
    • @MannySanchez 使用 OR 运算符,即 | - 像这样:"(&amp;(objectCategory=user)(objectClass=user)(|(department=Department1)(department=Department2)))" 您可以在此处阅读有关构建 LDAP 查询的更多信息:social.technet.microsoft.com/wiki/contents/articles/…
    猜你喜欢
    • 2023-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2012-05-02
    相关资源
    最近更新 更多