Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

ASP.NET Identityでユーザーに役割(ロール)を持たせる

ASP.NET Identity入門 第11回

2015/04/20 14:00

 前回はユーザーを管理する画面を作成し、ユーザー情報の変更、削除、および追加をできるようにしました。しかし、実際のアプリケーションではセキュリティの観点上、ユーザー情報の管理は「管理者」だけができるようにするべきです。ASP.NET Identityでは「管理者」、「一般ユーザー」といった役割を「ロール」という考えで実現します。今回はこのロール機能を使って、ユーザー管理機能を管理者だけが使えるようにしてみましょう。

目次

ロール機能とは

 アプリケーションを使う上で、特定のユーザーにのみ操作を制限したいというケースはよくあることです。例えば、社員の管理を行う機能は、一般のユーザーが勝手に操作できては困るので、社員を管理する「役割」を持ったユーザーでのみ操作を行えるようにする、といった具合です。

 こういった時に一番簡単なのは、「操作が可能である」という情報を各機能、各ユーザー毎に設定することです。この方法は機能数、ユーザー数が少なければ、うまくいくでしょう。しかし、どちらかが多くなってくると、途端に管理しきれなくなってきます。

 そこで、この問題を解決するために「役割(ロール、権限)」という概念を導入します。まずある一定の役割を持ったユーザーをグループ化ます。そして、各機能に対してはユーザー単位でなくロール単位で操作できるかどうかを設定します。こうすることで、役割やユーザーの増減に伴う影響を少なくできるのです。

 ASP.NET Identityでもロールをサポートする機能は提供されています。今回はこのロール機能を使い、前回作成したユーザー管理画面を「管理者」だけが操作できるようにしてみましょう。

ロール機能の組み込みイメージ

 コードの説明に入る前に、ロール機能を組み込んだ動作イメージを説明しましょう。サンプルは前回のものに手を加える形で作成しています。

 まず、ログイン前はユーザー管理画面へのリンクがメニューに表示されません(図1)。

図1:ログイン前のメニュー
図1:ログイン前のメニュー

 「管理者」ロールに属するユーザーでログインすると、メニューに追加されます(図2)。

図2:管理者ユーザーでログイン後のメニュー
図2:管理者ユーザーでログイン後のメニュー

 ログインユーザーが管理者でない場合は、ログイン後でもメニューには追加されません(図3)。

図3:一般ユーザーでログイン後のメニュー
図3:一般ユーザーでログイン後のメニュー

 ユーザー管理画面には、管理者かどうかを設定する列を追加します。行を編集すると、チェックボックスが表示されるので、管理者にしたい場合はチェックを入れて更新します(図4)。

図4:管理者設定が可能なユーザー管理画面
図4:管理者設定が可能なユーザー管理画面

 なお、管理者以外でユーザー管理画面をURL指定で直接開こうとしても、ログイン画面に遷移させるよう承認設定も行います。

ロール管理用クラス群作成

 動作イメージが分かったところで、今度はロール機能をどのように組み込んでいくか説明していきます。最初に行うのは、ロール管理用の各種クラス群の作成です。

ロール

 まずは「ロール」そのものを表すApplicationRoleクラスを作成します(リスト1)。

リスト1 ロールクラス(Models\IdentityModels.csより)
/// <summary>
/// ロール情報です。
/// </summary>
public class ApplicationRole : IdentityRole
{
}

 ApplicationRoleクラスは、Microsoft.AspNet.Identity.EntityFramework.IdentityRoleクラスを継承して作成します。このクラスはIdとNameプロパティがすでに定義されています。今回は特にロールに追加すべき項目がありませんので、ApplicationRoleクラスのメンバーは追加する必要がありません。

ロールマネージャー

 次に、ロールの読み書きを行うためのApplicationRoleManagerクラスを作成します(リスト2)。

リスト2 ロールマネージャークラス(App_Start\IdentityConfig.csより)
/// <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)。

リスト3 ロールマネージャーオブジェクトをOWINコンテキストに登録(App_Start\Startup.Auth.csより)
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);
    ...(略)...
  }
}

 以上でアプリケーション側からロールを操作する準備が整いました。


著者プロフィール

  • WINGSプロジェクト 高野 将(タカノ ショウ)

    <個人紹介> 新潟県長岡市在住の在宅リモートワークプログラマー。家事や育児、仕事の合間に長岡IT開発者勉強会(NDS)、Niigata.NET、TDDBCなどのコミュニティに関わったり、Web記事や書籍などの執筆を行ったりしている。著書に『アプリを作ろう! Visual C#入門 Visual C...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

バックナンバー

連載:ASP.NET Identity入門

もっと読む

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5