Как получить имя пользователя в Active Directory из отображаемого имени в C #? - PullRequest
16 голосов
/ 23 марта 2012

Я хочу получить идентификатор пользователя в 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.Есть идеи?

Ответы [ 2 ]

32 голосов
/ 24 марта 2012

Я полагаю, что вы можете сделать это намного проще, чем с помощью ответа Дэвида, используя встроенную функциональность пространства имен System.DirectoryServices.AccountManagement (S.DS.AM).

По сути, вы можете определить контекст домена и легко найти пользователей и / или группы в 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;
        }
    }
}
8 голосов
/ 24 марта 2012

UserPrincipal имеет метод GetUnderlyingObject(), который возвращает DirectoryEntry.

Получить 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-Account-Name (имя пользователя @ домен):

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

А вот полный список всех атрибутов Active Directory. Используйте "Ldap-Display-Name" при получении значения от Properties
например Properties["Ldap-Display-Name"]

Отображаемое имя (FirstName MI LastName) может пригодиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...