ロール機能とは
アプリケーションを使う上で、特定のユーザーにのみ操作を制限したいというケースはよくあることです。例えば、社員の管理を行う機能は、一般のユーザーが勝手に操作できては困るので、社員を管理する「役割」を持ったユーザーでのみ操作を行えるようにする、といった具合です。
こういった時に一番簡単なのは、「操作が可能である」という情報を各機能、各ユーザー毎に設定することです。この方法は機能数、ユーザー数が少なければ、うまくいくでしょう。しかし、どちらかが多くなってくると、途端に管理しきれなくなってきます。
そこで、この問題を解決するために「役割(ロール、権限)」という概念を導入します。まずある一定の役割を持ったユーザーをグループ化ます。そして、各機能に対してはユーザー単位でなくロール単位で操作できるかどうかを設定します。こうすることで、役割やユーザーの増減に伴う影響を少なくできるのです。
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); ...(略)... } }
以上でアプリケーション側からロールを操作する準備が整いました。