如何在C#中获取当前用户的Active Directory详细信息

38
我正在开发一款使用Windows身份验证的C#和ASP.Net应用程序。 即在Web.config中:
<system.web>
    <authentication mode="Windows" />
</system.web>

我想从Active Directory中获取当前用户的详细信息(全名、电子邮件地址等)。


我可以通过以下方式获取他们的Windows 2000之前的用户登录名(例如:SOMEDOMAIN\someuser):

string username = HttpContext.Current.Request.ServerVariables["AUTH_USER"];

我已经通过使用用户的当前登录名(而不是他们的Windows 2000之前的用户登录名)来解决了LDAP查询问题:

DirectorySearcher adSearch = new DirectorySearcher(
        "(userprincipalname=someuser@somedomain.com.au)");
SearchResult adSearchResult = adSearch.FindOne();

然而,我不知道如何使用用户的pre W2K登录名搜索AD,或者获取他们的登录名以“someuser@somedomain.com.au”的格式。

有什么想法吗?

4个回答

55

“pre Windows 2000”名称即DOMAIN\SomeBody中的Somebody部分被称为sAMAccountName。

因此,请尝试:

using(DirectoryEntry de = new DirectoryEntry("LDAP://MyDomainController"))
{
   using(DirectorySearcher adSearch = new DirectorySearcher(de))
   {
     adSearch.Filter = "(sAMAccountName=someuser)";
     SearchResult adSearchResult = adSearch.FindOne();
   }
}

someuser@somedomain.com.au是UserPrincipalName,但它不是必填字段。


8
不,不是这样的。 sAMAccountName 不包含 "DOMAIN" 部分,因此对于整个域的查询毫无用处。 - Chris KL
事实上,缺少“DOMAIN\”是有问题的。 - user166390
抱歉,该注释与代码示例不匹配。是的,sAMAccountName只是DOMAIN\username中的“用户名”部分。sAMAccountName没有森林的概念,因为它是一个Windows2000之前的概念。如果您需要搜索W2k+域森林,请使用UPN username@DOMAIN - Alan

45

Alan已经给出了正确的答案 - 使用sAMAccountName来过滤您的用户。

我想对您使用DirectorySearcher提出建议 - 如果您只需要一两个信息,请将它们添加到DirectorySearcher"PropertiesToLoad"集合中。

这样,就不必检索整个大用户对象,然后挑选出一两个项目,而是只返回您需要的那些部分。

示例:

adSearch.PropertiesToLoad.Add("sn");  // surname = last name
adSearch.PropertiesToLoad.Add("givenName");  // given (or first) name
adSearch.PropertiesToLoad.Add("mail");  // e-mail addresse
adSearch.PropertiesToLoad.Add("telephoneNumber");  // phone number

这些只是您需要指定的通常的AD/LDAP属性名称。


11

添加对COM“Active DS类型库”的引用

            Int32 nameTypeNT4               = (int) ActiveDs.ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_NT4;
            Int32 nameTypeDN                = (int) ActiveDs.ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_1779;
            Int32 nameTypeUserPrincipalName = (int) ActiveDs.ADS_NAME_TYPE_ENUM.ADS_NAME_TYPE_USER_PRINCIPAL_NAME;

            ActiveDs.NameTranslate nameTranslate = new ActiveDs.NameTranslate();

            // Convert NT name DOMAIN\User into AD distinguished name 
            // "CN= User\\, Name,OU=IT,OU=All Users,DC=Company,DC=com"
            nameTranslate.Set(nameTypeNT4, ntUser);

            String distinguishedName = nameTranslate.Get(nameTypeDN);

            Console.WriteLine(distinguishedName);

            // Convert AD distinguished name "CN= User\\, Name,OU=IT,OU=All Users,DC=Company,DC=com" 
            // into NT name DOMAIN\User
            ntUser = String.Empty;
            nameTranslate.Set(nameTypeDN, distinguishedName);
            ntUser = nameTranslate.Get(nameTypeNT4);
            Console.WriteLine(ntUser);

            // Convert NT name DOMAIN\User into AD UserPrincipalName Name.User@Company.com
            nameTranslate.Set(nameTypeNT4, ntUser);
            String userPrincipalName = nameTranslate.Get(nameTypeUserPrincipalName);

            Console.WriteLine(userPrincipalName);

1
使用NameTranslate获取DSN是正确的方法。 - Johannes Kuhn
嗨,我尝试做这个,但是当我添加“Active DS Type Library”时,它会带有黄色三角形的警告。我在Windows 10上,你知道发生了什么吗?谢谢。 - Lautaro Cozzani

4
如果您正在使用.NET 3.5 SP1+,更好的方法是查看以下内容:
System.DirectoryServices.AccountManagement namespace.

它有查找人员的方法,你可以使用任何用户名格式,并返回大部分基本信息。如果需要帮助加载更复杂的对象和属性,请查看http://umanage.codeplex.com的源代码,那里面都有。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接