C# 检索用户信息的快速方法 Active Directory

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/456523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 04:05:08  来源:igfitidea点击:

Quick way to retrieve user information Active Directory

c#active-directory

提问by Adyt

How to query user information from Active Directory? I have code that works, but it's really slow. I'm using C#. This is the code I currently use:

如何从Active Directory查询用户信息?我有有效的代码,但它真的很慢。我正在使用 C#。这是我目前使用的代码:

    static void Main(string[] args)
    {
        SearchResultCollection sResults = null;

        try
        {
            //modify this line to include your domain name
            string path = "LDAP://EXTECH";
            //init a directory entry
            DirectoryEntry dEntry = new DirectoryEntry(path);

            //init a directory searcher
            DirectorySearcher dSearcher = new DirectorySearcher(dEntry);

            //This line applies a filter to the search specifying a username to search for
            //modify this line to specify a user name. if you want to search for all
            //users who start with k - set SearchString to "k"
            dSearcher.Filter = "(&(objectClass=user))";

            //perform search on active directory
            sResults = dSearcher.FindAll();

            //loop through results of search
            foreach (SearchResult searchResult in sResults)
            {
                if (searchResult.Properties["CN"][0].ToString() == "Adit")
                {
                    ////loop through the ad properties
                    //foreach (string propertyKey in
                    //searchResult.Properties["st"])
                    //{

                        //pull the collection of objects with this key name
                        ResultPropertyValueCollection valueCollection =
                        searchResult.Properties["manager"];

                        foreach (Object propertyValue in valueCollection)
                        {

                            //loop through the values that have a specific name
                            //an example of a property that would have multiple
                            //collections for the same name would be memberof
                            //Console.WriteLine("Property Name: " + valueCollection..ToString());
                            Console.WriteLine("Property Value: " + (string)propertyValue.ToString());

                            //["sAMAccountName"][0].ToString();
                        }
                    //}
                    Console.WriteLine(" ");
                }
            }
        }
        catch (InvalidOperationException iOe)
        {
            //
        }
        catch (NotSupportedException nSe)
        {
            //
        }
        finally
        {

            // dispose of objects used
            if (sResults != null)
                sResults.Dispose();

        }
        Console.ReadLine();
    }

What would faster code look like to get user information from AD?

从 AD 获取用户信息的更快代码是什么样的?

采纳答案by barneytron

The reason why your code is slow is that your LDAPquery retrieves every single user object in your domain even though you're only interested in one user with a common name of "Adit":

您的代码缓慢的原因是您的LDAP查询会检索您域中的每个用户对象,即使您只对一个通用名称为“Adit”的用户感兴趣:

dSearcher.Filter = "(&(objectClass=user))";

So to optimize, you need to narrow your LDAP query to just the user you are interested in. Try something like:

因此,要优化,您需要将 LDAP 查询范围缩小到您感兴趣的用户。尝试以下操作:

dSearcher.Filter = "(&(objectClass=user)(cn=Adit))";

In addition, don't forget to dispose these objects when done:

此外,不要忘记在完成后处理这些对象:

  • DirectoryEntry dEntry
  • DirectorySearcher dSearcher
  • 目录项 dEntry
  • 目录搜索器 dSearcher

回答by Handleman

I'm not sure how much of your "slowness" will be due to the loop you're doing to find entries with particular attribute values, but you can remove this loop by being more specific with your filter. Try this page for some guidance ... Search Filter Syntax

我不确定您的“缓慢”有多少是由于您正在执行查找具有特定属性值的条目的循环,但是您可以通过更具体地使用过滤器来删除此循环。试试这个页面以获得一些指导......搜索过滤器语法

回答by Steve Evans

You can simplify this code to:

您可以将此代码简化为:

        DirectorySearcher searcher = new DirectorySearcher();
        searcher.Filter = "(&(objectCategory=user)(cn=steve.evans))";

        SearchResultCollection results = searcher.FindAll();

        if (results.Count == 1)
        {
            //do what you want to do
        }
        else if (results.Count == 0)
        {
            //user does not exist
        }
        else
        {
            //found more than one user
            //something is wrong
        }

If you can narrow down where the user is you can set searcher.SearchRoot to a specific OU that you know the user is under.

如果您可以缩小用户所在的范围,您可以将 searcher.SearchRoot 设置为您知道用户所在的特定 OU。

You should also use objectCategory instead of objectClass since objectCategory is indexed by default.

您还应该使用 objectCategory 而不是 objectClass,因为 objectCategory 默认是索引的。

You should also consider searching on an attribute other than CN. For example it might make more sense to search on the username (sAMAccountName) since it's guaranteed to be unique.

您还应该考虑搜索 CN 以外的属性。例如,搜索用户名 (sAMAccountName) 可能更有意义,因为它保证是唯一的。

回答by marc_s

Well, if you know where your user lives in the AD hierarchy (e.g. quite possibly in the "Users" container, if it's a small network), you could also bind to the user account directly, instead of searching for it.

好吧,如果您知道您的用户在 AD 层次结构中的位置(例如,很可能在“用户”容器中,如果它是一个小型网络),您也可以直接绑定到用户帐户,而不是搜索它。

DirectoryEntry deUser = new DirectoryEntry("LDAP://cn=John Doe,cn=Users,dc=yourdomain,dc=com");

if (deUser != null)
{
  ... do something with your user
}

And if you're on .NET 3.5 already, you could even use the vastly expanded System.DirectorySrevices.AccountManagement namespace with strongly typed classes for each of the most common AD objects:

如果您已经在 .NET 3.5 上,您甚至可以使用极大扩展的 System.DirectorySrevices.AccountManagement 命名空间,并为每个最常见的 AD 对象使用强类型类:

// bind to your domain
PrincipalContext pc = new PrincipalContext(ContextType.Domain, "LDAP://dc=yourdomain,dc=com");

// find the user by identity (or many other ways)
UserPrincipal user = UserPrincipal.FindByIdentity(pc, "cn=John Doe");

There's loads of information out there on System.DirectoryServices.AccountManagement - check out this excellent articleon MSDN by Joe Kaplan and Ethan Wilansky on the topic.

System.DirectoryServices.AccountManagement 上有大量信息 - 请查看Joe Kaplan 和 Ethan Wilansky 在 MSDN 上撰写的有关该主题的优秀文章

回答by om471987

You can call UserPrincipal.FindByIdentityinside System.DirectoryServices.AccountManagement:

你可以UserPrincipal.FindByIdentity在里面打电话System.DirectoryServices.AccountManagement

using System.DirectoryServices.AccountManagement;

using (var pc = new PrincipalContext(ContextType.Domain, "MyDomainName"))
{
    var user = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, "MyDomainName\" + userName);
}