web-dev-qa-db-ja.com

C#の表示名からActive Directoryのユーザー名を取得する方法

ユーザーの表示名を使用して、Active Directory内のユーザーのユーザーIDを取得できるようにしたい。表示名はデータベースから取得され、次のコードを使用してそのユーザーのセッション中に保存され、表示名を取得します。

_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;
    }
_

今回は、Active Directoryログイン名を返すGetUserIdFromDisplayName()という名前のメソッドを用意します。何か案は?

16
JF Beaulieu

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;
        }
    }
}

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;
        }
    }
}
33
marc_s

UserPrincipalには、DirectoryEntryを返すメソッドGetUnderlyingObject()があります。

プリンシパルから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アカウント名(ユーザー名@ドメイン)を取得するには:

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

そして、これがすべてのActive Directory属性の 網羅的リスト です。 Propertiesから値を取得するときは、「Ldap-Display-Name」を使用します
例えば。 Properties["Ldap-Display-Name"]

Display-Name (FirstName MI LastName)が便利かもしれません。

8
David