ロール機能とは
アプリケーションを使う上で、特定のユーザーにのみ操作を制限したいというケースはよくあることです。例えば、社員の管理を行う機能は、一般のユーザーが勝手に操作できては困るので、社員を管理する「役割」を持ったユーザーでのみ操作を行えるようにする、といった具合です。
こういった時に一番簡単なのは、「操作が可能である」という情報を各機能、各ユーザー毎に設定することです。この方法は機能数、ユーザー数が少なければ、うまくいくでしょう。しかし、どちらかが多くなってくると、途端に管理しきれなくなってきます。
そこで、この問題を解決するために「役割(ロール、権限)」という概念を導入します。まずある一定の役割を持ったユーザーをグループ化ます。そして、各機能に対してはユーザー単位でなくロール単位で操作できるかどうかを設定します。こうすることで、役割やユーザーの増減に伴う影響を少なくできるのです。
ASP.NET Identityでもロールをサポートする機能は提供されています。今回はこのロール機能を使い、前回作成したユーザー管理画面を「管理者」だけが操作できるようにしてみましょう。
ロール機能の組み込みイメージ
コードの説明に入る前に、ロール機能を組み込んだ動作イメージを説明しましょう。サンプルは前回のものに手を加える形で作成しています。
まず、ログイン前はユーザー管理画面へのリンクがメニューに表示されません(図1)。
「管理者」ロールに属するユーザーでログインすると、メニューに追加されます(図2)。
ログインユーザーが管理者でない場合は、ログイン後でもメニューには追加されません(図3)。
ユーザー管理画面には、管理者かどうかを設定する列を追加します。行を編集すると、チェックボックスが表示されるので、管理者にしたい場合はチェックを入れて更新します(図4)。
なお、管理者以外でユーザー管理画面をURL指定で直接開こうとしても、ログイン画面に遷移させるよう承認設定も行います。
ロール管理用クラス群作成
動作イメージが分かったところで、今度はロール機能をどのように組み込んでいくか説明していきます。最初に行うのは、ロール管理用の各種クラス群の作成です。
ロール
まずは「ロール」そのものを表すApplicationRoleクラスを作成します(リスト1)。
/// <summary>
/// ロール情報です。
/// </summary>
public class ApplicationRole : IdentityRole
{
}
ApplicationRoleクラスは、Microsoft.AspNet.Identity.EntityFramework.IdentityRoleクラスを継承して作成します。このクラスはIdとNameプロパティがすでに定義されています。今回は特にロールに追加すべき項目がありませんので、ApplicationRoleクラスのメンバーは追加する必要がありません。
ロールマネージャー
次に、ロールの読み書きを行うためのApplicationRoleManagerクラスを作成します(リスト2)。
/// <summary>
/// ロールを管理します。
/// </summary>
public class ApplicationRoleManager : RoleManager<ApplicationRole, string>
{
public ApplicationRoleManager(IRoleStore<ApplicationRole, string> store)
: base(store) { }
public static ApplicationRoleManager Create(
IdentityFactoryOptions<ApplicationRoleManager> options,
IOwinContext context)
{
//(1)DbContext取得
var dbContext = context.Get<ApplicationDbContext>();
//(2)ロールストア作成
var roleStore = new RoleStore<ApplicationRole>(dbContext);
//(3)ロールマネージャー作成
var manager = new ApplicationRoleManager(roleStore);
if (!manager.Roles.Any())
{
//(4)初回に管理者ロールを作成する
manager.Create(new ApplicationRole
{
Name = "Administrator"
});
}
return manager;
}
}
ApplicationRoleManagerクラスは、Microsoft.AspNet.Identity.RoleManager<TRole, TKey>クラスを継承して作成します。継承する際、型パラメーターのTRoleには先ほど定義したApplicationRoleクラスを、TKeyにはロールのキーとなるstring型を指定します。
ApplicationRoleManagerクラスには、自らのインスタンスを作成するためのCreate静的メソッドを追加します。Create静的メソッドで行うことは以下の通りです。
(1) DbContext取得
ASP.NET Identityで用いるEntity FrameworkのDbContextは、OWINコンテキストから取得します。
(2)ロールストア作成
DbContextを使ってロール情報をDBから出し入れする、RoleStoreオブジェクトを作成します。
(3)ロールマネージャー作成
ロールストアを通じてロールの管理を行うためのApplicationRoleManagerオブジェクトを作成します。
(4)管理者ロール作成
本来であればロールマネージャーを使いロールを管理する画面も作成すべきですが、今回はあくまでサンプルなので、初回起動時に管理者ロール「Administrator」を作成します。ロールマネージャーのRolesプロパティはIQueryable<ApplicationRole>型なので、LINQを使って処理を行えます。今回はすでに登録されたロールがない場合だけ、管理者ロールを作成しています。
作成したロールマネージャークラスのオブジェクトは、ApplicationUserManagerと同様に、OWINコンテキストに登録しておきます(リスト3)。
public partial class Startup
{
// 認証の構成の詳細については、http://go.microsoft.com/fwlink/?LinkId=301883 を参照してください。
public void ConfigureAuth(IAppBuilder app)
{
// 要求ごとに 1 つのインスタンスを使用するよう db コンテキスト、ユーザー マネージャー、サインイン マネージャーを構成します
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
// ロール管理オブジェクトをOWINコンテキストに登録
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
...(略)...
}
}
以上でアプリケーション側からロールを操作する準備が整いました。



