如何从C#中的显示名称获取Active Directory中的用户名?

我希望能够使用该用户的显示名称获取Active Directory中用户的用户标识。 显示名称是从数据库中获取的,并且在该用户会话期间使用以下代码存储以获取显示名称:

using System.DirectoryServices.AccountManagement; private string GetDisplayName() { // set up domain context PrincipalContext ctx = new PrincipalContext(ContextType.Domain); // find currently logged in user UserPrincipal user = UserPrincipal.Current; return user.DisplayName; } 

这一次,我想有一个名为GetUserIdFromDisplayName()的方法,它返回Active Directory登录名。 有任何想法吗?

我相信通过使用System.DirectoryServices.AccountManagement (S.DS.AM)命名空间的内置function,您可以比使用David的答案更容易做到这一点。

基本上,您可以定义域上下文并在AD中轻松查找用户和/或组:

 using System.DirectoryServices.AccountManagement; private string GetUserIdFromDisplayName(string displayName) { // set up domain context using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain)) { // find user by display name UserPrincipal user = UserPrincipal.FindByIdentity(ctx, displayName); // if (user != null) { return user.SamAccountName; // or maybe you need user.UserPrincipalName; } else { return string.Empty; } } } 

我认为没有必要去底层的DirectoryEntry对象 – 除非UserPrincipal的所有属性都不是你想要的。

PS:如果按显示名称搜索不起作用(我手边没有AD来测试它) – 您也可以随时使用PrincipalSearcher查找您的用户:

 using System.DirectoryServices.AccountManagement; private string GetUserIdFromDisplayName(string displayName) { // set up domain context using(PrincipalContext ctx = new PrincipalContext(ContextType.Domain)) { // define a "query-by-example" principal - here, we search for a UserPrincipal // and with the display name passed in UserPrincipal qbeUser = new UserPrincipal(ctx); qbeUser.DisplayName = displayName; // create your principal searcher passing in the QBE principal PrincipalSearcher srch = new PrincipalSearcher(qbeUser); // find match - if exists UserPrincipal user = srch.FindOne() as UserPrincipal; if (user != null) { return user.SamAccountName; // or maybe you need user.UserPrincipalName; } else { return string.Empty; } } } 

UserPrincipal有一个方法GetUnderlyingObject() ,它将返回DirectoryEntry

从Principal获取DirectoryEntry:

 private DirectoryEntry GetDirectoryEntryFromUserPrincipal(Principal user) { return (DirectoryEntry)user.GetUnderlyingObject(); } 

从域名和帐户名获取DirectoryEntry:

 private DirectoryEntry GetDirectoryEntryFromDomainAndUsername(string domainName, string userName) { // Get the sid from the NT account name var sid = (SecurityIdentifier) new NTAccount(domainName, accountName) .Translate(typeof(SecurityIdentifier)); // Get the directory entry for the LDAP service account var serviceEntry = new DirectoryEntry("LDAP://{address}", "serviceUsername", "servicePassword"); var mySearcher = new DirectorySearcher(serviceEntry) { Filter = string.Format("(&(ObjectSid={0}))", sid.Value) }; return mySearcher.FindOne().GetDirectoryEntry(); } 

一旦有了DirectoryEntry使用Guid属性来获取条目的Object-Guid

 private Guid GetObjectGuidFromDirectoryEntry(DirectoryEntry entry) { // return the Guid this is the Object-Guid (ignore NativeGuid) return entry.Guid; } 

要根据目录帐户跟踪应用程序中的用户帐户,请始终使用Object-Guid作为“创建对象时无法更改此值。”
如果用户更改域名,或者更常见的是更改其名称(婚姻,法定名称更改等),则NT和SAM帐户名称可能会更改,并且不应用于跟踪用户。

获取NT帐户名称(域\用户名):

 private string GetNTAccountNameFromDirectoryEntry(DirectoryEntry entry) { PropertyValueCollection propertyValueCollection = entry.Properties["objectsid"]; SecurityIdentifier sid = new SecurityIdentifier((byte[]) propertyValueCollection[0], 0); NTAccount ntAccount = (NTAccount)sid.Translate(typeof (NTAccount)); return account.ToString(); } 

要获取SAM帐户名称(username @ domain):

 private string GetSAMAccountFromDirectoryEntry(DirectoryEntry entry) { return entry.Properties["Name"].Value; } 

这是所有Active Directory属性的详尽列表 。 从Properties获取值时,请使用“Ldap-Display-Name”
例如Properties["Ldap-Display-Name"]

显示名称 (FirstName MI LastName)可能会派上用场。