はじめに
Enterprise Libraryは様々な機能を提供しています。しかし、提供されていない機能が必要となった場合には、何らかの拡張を行う必要があります。
本稿では、拡張を行う際の方法を例を挙げて説明します。
対象読者
Enterprise Libraryを用いている開発者。
必要な環境
- Visual Studio .NET 2003上で動作確認しています。
- Enterprise Library, June 2005が必要です。
Enterprise Libraryの構成
Enterprise Libraryの機能は、大きく分けると2つのレベルで定義されています。
- Application Block
- Provider
例えば、Security Application BlockというApplication Blockは、Authentication、Authorization、Profile、Role、Security CacheといったProviderを用いています。このうち、Authentication Providerとしては、Database Authentication Providerが提供されています。
今回は、新しい種類のAuthentication ProviderとしてXML Authentication Providerを作成します。
Authentication Providerについて
まずは、Security Application BlockにおけるAuthentication Providerのインタフェースを確認します。
「(インストール ディレクトリ)\src\Security\AuthenticationProvider.cs」で定義されるIAuthenticationProviderが対象のインタフェースです。
bool Authenticate(object credentials, out IIdentity identity);
リファレンスを参照すると、
credential
に認証情報が渡されます。identity
にアイデンティティを格納します。- 認証に成功したら
true
を、失敗したらfalse
を返します。
ということがわかります。
プログラムの作成
では、プログラムを作成してみましょう。
呼び出し側プログラム
まずは、呼び出し側プログラムを作成しておきます。この部分は、既存のProviderを使用する場合と全く同じコードです。したがって、既存のProviderを使用するコードが既にあれば、そのまま(再コンパイルも不要)使用することが可能です。この場合、新規に作成するProviderを単に別アセンブリとして作成し、同じディレクトリに配置すれば動作します。
参照設定に、Enterprise Libraryで提供される「Microsoft.Practices.EnterpriseLibrary.Security.dll」と「Microsoft.Practices.Enterpriselibrary.Configuration.dll」を加えておきます。
using System.Security.Principal; using Microsoft.Practices.EnterpriseLibrary.Security; private bool Authenticate(string user, string password, out IIdentity identity) { IAuthenticationProvider authenticationProvider = AuthenticationFactory.GetAuthenticationProvider(); NamePasswordCredential credential = new NamePasswordCredential(user, password); return authenticationProvider .Authenticate(credential, out identity); }
対象のXMLファイル
ユーザ・パスワードを「authentication.xml」に定義しておきます。
<?xml version="1.0" encoding="utf-8" ?> <users> <user id="test1" password="password1" /> <user id="test2" password="password2" /> </users>
構成ツールでの設定
通常通り構成ツールを起動して、「app.config」(あるいは「web.config」)を開き、[Security Application Block]を追加します。
Authenticationで[New]-[Custom Authentication Provider]を選択します。参照しやすくするため、名前を変更します。
その後、Providerが参照する構成情報を設定します。Custom Providerの場合、構成情報はExtensions
プロパティで設定します。Extensions
プロパティを選択すると右端に[…]ボタンが表示されますので、クリックして[コレクション エディタ]を開きます。
ここにProvider独自の名前と値の組を設定することができます。これを、Providerのコード内から参照することになります。
今回は、以下の値を設定しました。
名前 | 用途 | 今回の設定値 |
FileName | 対象のXMLファイル名を指定します。 | authentication.xml |
Path | ユーザ全体を表すXPath式を指定します。 | /users/user |
UserPath | ユーザIDを表す、Pathからの相対XPath式を指定します。 | @id |
PasswordPath | パスワードを表す、Pathからの相対XPath式を指定します。 | @password |
最後に、対象のCustom Providerのクラスを参照します。まだ実装を行っていなければ参照ができないので、その場合は実装後に再度構成ツールを実行する必要があります。
TypeNameプロパティを選択すると右端に[…]ボタンが表示されますので、クリックして[Type Selector]を開きます。
ここで、実装を行ったアセンブリとクラスを選択します。

これで設定ができましたので、保存します。
設定を取得する部分
既存のAuthenticationProviderを参考にして、以下のようなコードを作成しました。この部分のコードは、対象となるProviderによってConfigurationView
の型が変わること以外は、あまり変わらないのではないかと思います。
private SecurityConfigurationView securityConfigurationView; public override void Initialize(ConfigurationView configurationView) { // 引数にSecurityConfigurationViewが渡されていることを確認します ArgumentValidation.CheckForNullReference(configurationView, "configurationView"); ArgumentValidation.CheckExpectedType(configurationView, typeof(SecurityConfigurationView)); // 渡されたSecurityConfigurationViewを保持します securityConfigurationView = (SecurityConfigurationView)configurationView; }
処理本体
処理本体です。まずは、引数のチェックと構成情報の取得を行います。Providerによって引数の型や構成情報の型が異なりますが、この部分もあまり変わらないと思います。
public bool Authenticate(object credentials, out IIdentity identity) { // 引数にNamePasswordCredentialが渡されていることを確認します ArgumentValidation.CheckForNullReference(credentials, "credentials"); ArgumentValidation.CheckExpectedType(credentials, typeof(NamePasswordCredential)); NamePasswordCredential namePasswordCredential = (NamePasswordCredential)credentials; // SecurityConfigurationViewから設定情報を取得します // 「Custom Authentication Provider」として設定された場合、 // CustomAuthenticationProviderDataが作成されます CustomAuthenticationProviderData providerData = (CustomAuthenticationProviderData)securityConfigurationView .GetAuthenticationProviderData(ConfigurationName);
その後、実際の処理を行います。ここで、カスタム構成情報のExtensions
プロパティに設定した名前と値の組がproviderData.Extensions[名前]
で参照できます。
// 対象となるXMLファイルをロードします // 構成ツールでは、ファイル名をExtensionsのFileNameに設定します XmlDocument document = new XmlDocument(); document.Load(providerData.Extensions["FileName"]); // 構成ツールでは、ユーザ全体へのXPath式を // ExtensionsのPathに設定します string path = providerData.Extensions["Path"]; // 構成ツールでは、pathで指定されるノードから // ユーザIDへのXPath式をExtensionsのUserPathに設定します string userPath = providerData.Extensions["UserPath"]; // 構成ツールでは、pathで指定されるノードから // パスワードへのXPath式をExtensionsのPasswordPathに設定します string passwordPath = providerData.Extensions["PasswordPath"]; // 各ユーザを取得し、与えられたユーザIDと // パスワードが存在するかどうかを確認します foreach (XmlNode node in document.SelectNodes(path)) { XmlNode userNode = node.SelectSingleNode(userPath); if (userNode == null || userNode.Value != namePasswordCredential.Name) continue; XmlNode passwordNode = node.SelectSingleNode(passwordPath); if (passwordNode == null || passwordNode.Value != namePasswordCredential.Password) continue; // 見つかったので、GenericIdentityオブジェクトを生成します identity = new GenericIdentity(namePasswordCredential.Name); return true; } identity = null; return false; }
最後に
本稿では、既存のApplication Blockに用意されていないProviderを追加する方法を示しました。
今後は、追加した機能を構成ツールから利用できるようにする方法や、Application Blockそのものを作成する方法などを扱っていきたいと思います。