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

JF *_*ieu 16 .net 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;
    }
Run Code Online (Sandbox Code Playgroud)

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

mar*_*c_s 33

我相信通过使用System.DirectoryServices.AccountManagement(S.DS.AM)命名空间的内置功能,您可以比使用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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为没有必要去底层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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • +1,更简单,更快捷,并找到DOMAIN\USERID条目 (2认同)

Dav*_*vid 8

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

从Principal获取DirectoryEntry:

private DirectoryEntry GetDirectoryEntryFromUserPrincipal(Principal user)
{
    return (DirectoryEntry)user.GetUnderlyingObject();
}
Run Code Online (Sandbox Code Playgroud)

从域名和帐户名称获取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();
}
Run Code Online (Sandbox Code Playgroud)

一旦您DirectoryEntry使用该Guid属性获取条目的Object-Guid

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

要根据目录帐户跟踪应用程序中的用户帐户:始终使用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();
}
Run Code Online (Sandbox Code Playgroud)

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

private string GetSAMAccountFromDirectoryEntry(DirectoryEntry entry)
{
    return entry.Properties["Name"].Value;
}
Run Code Online (Sandbox Code Playgroud)

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

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