ホーム > .NET, ASP.NET 備忘録 > Form 認証に関するあれこれ

Form 認証に関するあれこれ

※この記事は One ASP.NET Advent Calender 2012 6日めのエントリーです。
ええ、6日分です。。。だれがなんといっても6日分です。。。

 

テンプレートに組み込まれているため、あまり考えもせずにさくっと使えてしまう Form 認証ですが、その実行を支えている要素についてあれこれ考えてみたいと思います。

 

○Form 認証を有効にする

Form 認証を有効にするには、web.config に authentication 要素を記述します。

<authentication mode="Forms" />

この設定は、ルートフォルダ直下のweb.configに記述する必要があります。

不思議なことに、 WebPages のテンプレートにはこの記述が存在しないのに、Form 認証が実行されます。
これは、SimpleMembershipProvider を含む WebMatrix.WebData.dll が登録されていると、アプリケーションの起動時に強制的に Form 認証を使うように設定されるためです。

 

○ログインの実行

WebFormsだとログインの実行に使われるのは Login コントロールです。
SqlMembershipProvier や Universal Membership Provider とともに使えば、コントロールを貼り付けるだけでログインの操作は自動でできるようになります。
ただ、これだとなかの動きはまったく見えませんね。

SimpleMembershipProvider とともに使われるのは WebSecurity.Login メソッドです。
ドキュメント中に記載がありますが、「ユーザーがログインすると、ASP.NET によって Cookie に認証トークンが設定されます。」
Loinコントロールも実は同じことをやっています。

この動きがはっきり見えるのは ASP.NET MVC 3 のテンプレート中の LogOn 時の動きです。
Membership.ValidateUser メソッドを使ってユーザーが登録されているかどうかを確認し、 FormsAuthentication.SetAuthCookie メソッドによって Cookie に認証トークンを設定しています。

ここで重要なことは、

  • ASP.NETのログインとはCookieに認証トークンを設定することである。
  • 認証トークンは FormsAuthentication.SetAuthCookie メソッドによって発行することができる

ということです。
なんらかの MembershipProvider を使わなくても、たとえば独自のデータベースの情報からユーザーが登録されているかどうかを判定して、FormsAuthentication.SetAuthCookie メソッドを使えば ASP.NET が用意している Form 認証の仕組みを使うことができるのです。

なお、Session の管理にも Cookie が使われますが、Session 用の Cookie と認証トークンとしての Cookie は別のものです。
Session と認証トークンはそれぞれ別に管理される、ということは覚えておいてよいことかと思います。

 

○ログインユーザーの認証

ログインすると Cookie に認証トークンが設定されることはわかりました。
では、この認証トークンはどのように使われるのでしょう。
このあたりは ASP.NET のフレームワークがうまくいろいろとやってくれるところです。
具体的には HttpApplication クラスのアプリケーションイベントの発生順をみてください。

ここの AuthenticateRequest イベントのタイミングで、フレームワークは認証トークンを解析し、HttpContext.User.Identity.IsAuthenticated に true を設定します。
まぁ、1リクエストを処理する間存在するある意味大域変数とも考えられる HttpContext にユーザーの情報を設定するわけです。

その後、AuthorizeRequest イベントのタイミングで承認(URLにアクセスする権限があるかの確認)が行われます。
承認の作業は HttpContext のユーザー情報を確認し、そのユーザーがアクセスする権限を持っているかどうかが判断されます。

 

○承認の設定

承認の設定は web.config に

<authorization>
  <deny users="?"/>
</authorization>

のように記述されます。
これは認証されていないユーザーへのアクセスを許可しない、という設定ですね。

web.config はフォルダごとに配置することが可能ですので、特定のフォルダに上記を含む web.config を配置すると、そのフォルダ内のリソースは認証されていないユーザーには表示されない、ということになります。

この設定は location 要素を利用することで特定のファイルにのみ設定を有効にすることも可能です。

<location path="Manage.aspx">
  <system.web>
    <authorization>
      <deny users="?"/>
    </authorization>
  </system.web>
</location>

また、location 要素にフォルダを設定することもできますので、各フォルダごとに web.config を配置するのではなく、ルートの web.config 内にすべての設定をまとめて記述することも可能です。

この承認の設定は、実際には URL に対して行われている、ということを理解するのが重要です。
ASP.NET MVC のように、フォルダの構成と URL の構成が一致しない場合、URL に合うように承認の設定を記述する必要があります。

ASP.NET MVC で /admin の中を認証ユーザーのみに公開したい、といったとき、 View フォルダ内の adminフォルダに 承認の設定を記述してもそれは有効になりません。
その場合、ルート直下にadminというフォルダを作成してしまってそこに承認の設定を配置するか、location を使って /admin にたいして承認の設定を記述すれば有効になります。

まぁ、実際には ASP.NET MVC では Authorize 属性をコントローラ(クラス)、またはアクション(メソッド)に設定することで承認の設定とするほうがわかりやすいでしょう。
この場合、web.config には承認の設定は記述しません。
そのため、HttpApplication の AuthorizeRequest イベント時には承認の解決は行われていません。
Authorize 属性は Actionフィルターの一種ですので、各アクションの実行直前のタイミングで承認が行われることになります。

○まとめ

ASP.NET の Form 認証がどのようにして実行されているかをまとめてみました。
ここに記述した内容が理解できていると、独自の認証の仕組みを構築するのに MembershipProvider のカスタマイズなんておおげさなことをしなくても、ちょっとした実装でそれなりの仕組みを構築できるようになっていることがわかるのではないかと思います。

実はこれから Membership の仕組みに新しいものが登場することになっています。(ロードマップ参照
ただ、ここに記述した認証/承認のベースの仕組みは ASP.NET 登場当時からのものであり、今後もこのベースそのものが変わることは考えにくいと思っています。
基礎となっている部分をしっかり理解していれば、新しい仕組みがでてきてもどこが違うのか、をおさえるだけで使えますから、このあたりの知識は無駄にならないんじゃないかなぁ、と思っています。

カテゴリー:.NET, ASP.NET 備忘録
  1. まだコメントはありません。
  1. No trackbacks yet.

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。