ユーザーの表示名を使用して、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()
という名前のメソッドを用意します。何か案は?
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;
}
}
}
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)が便利かもしれません。