私はMVC4イントラネットアプリケーションに取り組んでおり、Windows認証を使用しています。認証方法が使用するユーザーオブジェクト(@User)に追加し、Active Directoryからそのデータ(電子メール、電話番号など)を取得したいと思います。
カスタムのAuthorize属性を作成して、他のすべてのコントローラーが継承するコントローラーに追加できることは知っていますが、これが私が望むことを行うための正しい方法であるかどうかはわかりません。
私の最終目標は単純です。@ Userオブジェクトに、ActiveDirectoryを介して入力される追加のプロパティを持たせたいです。あなたが提供できるどんな助けにも感謝します。
あなたの既存の質問を見たとき、私はこの問題で他の人を助けるために私の解決策でStackOverflowに自分の質問を追加しようとしていました。これは非常に一般的なことのように思われますが、それを行う方法に関する情報は複数のソースに分散しており、追跡するのは困難です。完全なリソースは1つだけではないので、これがあなたや他の人に役立つことを願っています。
これを行う最良の方法は、UserPrincipal拡張機能を使用することです。基本的に、System.DirectoryServices.AccountManagement
からUserPrincipal
をサブクラス化し、独自の追加プロパティを追加します。これは、ExtensionGet
およびExtensionSet
(やや魔法の)メソッドを介して有効になります。
[DirectoryRdnPrefix("CN")]
[DirectoryObjectClass("user")]
public class UserPrincipalExtended : UserPrincipal
{
public UserPrincipalExtended(PrincipalContext context) : base(context)
{
}
public UserPrincipalExtended(PrincipalContext context, string samAccountName, string password, bool enabled)
: base(context, samAccountName, password, enabled)
{
}
[DirectoryProperty("title")]
public string Title
{
get
{
if (ExtensionGet("title").Length != 1)
return null;
return (string)ExtensionGet("title")[0];
}
set
{
ExtensionSet( "title", value );
}
}
[DirectoryProperty("department")]
public string Department
{
get
{
if (ExtensionGet("department").Length != 1)
return null;
return (string)ExtensionGet("department")[0];
}
set
{
ExtensionSet("department", value);
}
}
public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, string identityValue)
{
return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityValue);
}
public static new UserPrincipalExtended FindByIdentity(PrincipalContext context, IdentityType identityType, string identityValue)
{
return (UserPrincipalExtended)FindByIdentityWithType(context, typeof(UserPrincipalExtended), identityType, identityValue);
}
}
クラスの2つの属性は、ADのインスタンスに合わせてカスタマイズする必要があります。 DirectoryRdnPrefix
の値はADのRDN(相対識別名)である必要があり、DirectoryObjectClass
の値はuserObjectクラスのADのディレクトリオブジェクトタイプ名である必要があります。一般的なADドメインサービスのセットアップでは、両方とも上記のコードで使用されているとおりである必要がありますが、LDSのセットアップでは、異なる可能性があります。組織で使用する2つの新しいプロパティ、「title」と「department」を追加しました。それから、好きな他のプロパティを追加する方法のアイデアを得ることができます。基本的には、ここで提供したテンプレートを使用してプロパティを作成するだけです。プロパティには任意の名前を付けることができますが、DirectoryProperty
に渡され、コードブロック内の文字列値は、ADからのプロパティ名と一致する必要があります。これが適切な場所にあると、PrincipalContext
の代わりにUserPrincipal
をサブクラスで使用して、追加する必要のあるプロパティを持つユーザーオブジェクトを取得できます。
UserPrincipalExtended user = UserPrincipalExtended.FindByIdentity(
new PrincipalContext(ContextType.Domain), User.Identity.Name);
そして、UserPrincipal
インスタンスの他のプロパティと同じようにプロパティにアクセスします。
// User's title
user.Title
System.DirectoryServices.AccountManagement.UserPrincipal
に慣れていない場合は、GivenName
、Surname
、DisplayName
などのいくつかのユーザープロパティが組み込まれています。特にあなたの状況では、電話とメールについて具体的に言及したので、VoiceTelephoneNumber
とEmailAddress
があります。完全なリストは MSDN docs で確認できます。組み込み情報だけが必要な場合は、上で示したようにUserPrincipal
を拡張する必要はありません。あなたはただするでしょう:
UserPrincipal user = UserPrincipal.FindByIdentity(
new PrincipalContext(ContextType.Domain), User.Identity.Name);
ただし、10回のうち9回は組み込みでは不十分なので、残りを簡単に取得する方法を知っておくとよいでしょう。
最後に、これを使用するビューに@using
行を追加する必要がなかったので、先に進み、Views
フォルダーのweb.configに名前空間を追加しました。この部分は重要です。プロジェクト(およびエリアを使用している場合は各エリアの個々のViews
フォルダー)ではなく、Views
フォルダーのweb.configに追加する必要があります。
<system.web.webPages.razor>
...
<pages pageBaseType="System.Web.Mvc.WebViewPage">
<namespaces>
...
<add namespace="System.DirectoryServices.AccountManagement" />
<add namespace="Namespace.For.Your.Extension" />
</namespaces>
</pages>
</system.web.webPages.razor>