Подтвердить что ты не робот

Как получить имя пользователя в 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. Любые идеи?

4b9b3361

Ответ 1

Я считаю, что вы можете сделать это гораздо легче, чем с ответом Дэвида, используя встроенные функции пространства имен 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;
        }
    }
}

Ответ 2

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 (имя пользователя @domain):

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

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

Display-Name (FirstName MI LastName) может пригодиться.