.NET TIPS

[ASP.NET]構成ファイルのみでフォーム認証を実現するには?

山田 祥寛
2004/03/19

 Windows認証は、その名のとおり、認証のための設定や制御をWindowsやIISに委ねる機能である。よってWindows認証では、認証処理自体を実現するコーディングはほとんど必要ない。しかしその半面、細部の制御が利きにくいのも事実だ。

 例えば、ログイン用の画面1つとっても、Windows認証では味も素っ気もないダイアログしか表現できない。しかし、実際のアプリケーションにおいては、「アプリケーションを使用する場合の要件」「未登録ユーザーに対するユーザー登録の案内」「企業(組織)のロゴ」など、さまざまな情報をログイン画面に付加したいケースは少なくない。

 また、ユーザー情報を“Windowsのユーザー管理機能でしか管理できない”というのも、Windows認証の特徴であり、また大きな制約でもある。ある程度、ユーザー数が限られた(管理者が厳密にユーザーを把握できる規模の)イントラネット環境などでは、Windows標準機能によるユーザー管理でも問題はないが、不特定多数のユーザーを管理するインターネット環境においては、ユーザー管理工数自体が、アプリケーションのボトルネックとなる可能性も少なくない。

 こうした問題を解決するのが「フォーム認証」である。フォーム認証の特徴としては、大きく以下の3点を挙げることができる。

  • ログイン画面を自由にデザインできる
  • ユーザー管理の媒体を選ばない
  • 認証情報を永続的に保持することができる

 アプリケーションの構築という意味では、Windows認証よりは手間が多いのも事実であるが、インターネット上のWebシステムを設計するに際しては、Windows認証よりも有効(現実的)な選択肢であるといえよう。以下では、このフォーム認証を実現するまでの“最も標準的な”手順を紹介する。

1. アプリケーション・ルート配下のweb.configを設定する

 まずは、アプリケーション・ルート配下のweb.configに、<authentication>要素を追加する必要がある。<authentication>要素は、machine.config、またはアプリケーション・ルート直下のweb.configにしか記述することができないので注意が必要だ。例えば、アプリケーション・ルート配下のサブフォルダAにのみフォーム認証を設定したい場合にも、<authentication>要素の設定自体は、アプリケーション・ルート直下に記述する必要がある。

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms name="Insider.NET" loginUrl="login_vb.aspx"
          protection="All" timeout="30">
        <credentials passwordFormat="Clear">
          <user name="yyamada" password="12345" />
          <user name="nkakeya" password="12345" />
          <user name="kusui"   password="12345" />
        </credentials>
      </forms>
    </authentication>
  </system.web>
</configuration>
フォーム認証を使用する場合のweb.configの記述例
<authentication>要素を追加し、その配下に<forms>要素で一連の基本設定と、<credentials>要素でアクセスを認めるユーザーを定義する必要がある。

 Windows認証の場合には、<authentication>要素のmode属性に"Windows"と設定するのみであったが、フォーム認証(mode="Forms"属性)を設定した場合、<authentication>要素配下には<forms>要素で一連の基本設定と、<credentials>要素でアクセスを認める一連のユーザーを定義する必要がある。以下に、各要素で利用可能な属性の一覧を挙げておく。

要素 属性 概要 デフォルト
<forms> name 認証に使用するクッキー名 .ASPXAUTH
loginurl ログイン時に使用するログイン画面のURL default.aspx
protection 暗号化の種類(All|None|Encryption|Validation) All
timeout 認証クッキーの有効期限(分) 30
path 認証クッキーのパス /
requireSSL SSL通信の場合のみ認証クッキーを発行するかどうか false
slidingExpiration 要求ごとにクッキーの有効期限を更新するかどうか。true設定時には最後の要求がなくなってからの経過時間でタイムアウトを判断する false
<credentials> passwordFormat* 暗号化の種類(Clear|MD5|SHA1) -(必須項目なので、デフォルト値はない)
<user> name ユーザー名
password パスワード
フォーム認証に必要な要素と主な属性 *は必須属性)
各要素のより詳しい情報についてはMSDNの以下のページを参照されたい。
 ・ASP.NET設定スキーマ
 ・<forms>要素
 ・<credentials>要素
 ・<user>要素

 フォーム認証は、認証の是非を判断するためにクライアントに対してクッキーを発行するが(これを「認証クッキー」、または「チケット」という)、<forms>要素のprotection属性はこの認証クッキーの暗号化・検証チェックをするかどうかを決めるための属性だ。デフォルトはAll(暗号化・検証の双方を行う)であり、これは推奨設定でもある。None(暗号化・検証チェックともに行わない)、Encryption(暗号化のみ実施)、Validation(検証チェックのみ実施)というオプションを選択することができ、これによって認証時のパフォーマンスをいくらか軽減することが可能である。しかし、一般的には、このようなわずかなパフォーマンス維持のために安全性を損なうことは勧められない。

2. サブフォルダ配下の認定設定を行う

 「1. アプリケーション・ルート配下のweb.configを設定する」の設定によって、アプリケーションで採用する認証方法の定義は完了した。しかし、実際に認証を行うためには、具体的にどのフォルダに対して、どのユーザーのアクセスを認めるのかという定義情報が必要だ。これらは、実際にアクセス制限の対象となる構成ファイルに対して定義する必要がある。例えば、アプリケーション・ルート配下の「/auth」フォルダに対してアクセス制限を行う場合は、以下の定義も「/auth」フォルダ直下のweb.configに対して行う必要がある。

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <system.web>
    <authorization>
      <deny users="?" />
    </authorization>
  </system.web>
</configuration>
ユーザーのアクセス権限を定義したweb.configの記述例

 上記は、最も単純な<authorization>要素の定義だ。<authorization>要素配下では、アクセスを許可(または禁止)するユーザーを<allow>要素(または<deny>要素)にカンマ区切りで指定することができる。つまり、<authentication>要素でユーザーの判別(認証)を行ったASP.NETは、<authorization>要素でリソースごとのアクセス許可(認定)を行っているというわけだ。

 <allow>要素(または<deny>要素)のusers属性には、実ユーザー名のほかに、以下のようなワイルドカードを採用することができる。

ワイルドカード 概要
* すべてのユーザー
? 匿名ユーザー
users属性で利用可能なワイルドカード

 例えば、machine.configの中身を参照してみると、以下のような記述が確認できるはずである。

<allow users="*" />

 つまり、ASP.NETではデフォルトで「全ユーザー」のアクセスを認めているというわけである。ところが、「/auth」フォルダでは「匿名ユーザーを拒否(deny users="?")」した。逆にいえば、認証されたユーザーであるならば、誰でもリソースにアクセスできることを意味する。

 ちなみに、もしも特定のユーザー(例えば、“yyamada”と“nkakeya”)に対してのみアクセスを許可したいという場合には、以下のように記述すればよい。

<authorization>
  <allow users="yyamada,nkakeya" />
  <deny users="*" />
</authorization>
“yyamada”と“nkakeya”に対してのみアクセスを許可する記述例

 これによって、すべてのユーザーを拒否したうえで、あらためてyyamada、nkakeyaユーザーにのみアクセスを認めることができる。

 <authentication>要素はアプリケーション・ルート直下のweb.config(またはmachine.config)にしか記述することができないが、<authorization>要素はサブフォルダのweb.configに記述することができる。ここでは「/auth」フォルダに対してのみ<authorization>要素を記述したが、適宜必要に応じてアクセス制限したいフォルダにweb.configを追加すればよいだろう。

3. ログイン画面を作成する

 さて、最後にユーザー認証を行うためのログイン画面を用意してみよう。

<%@ Page ContentType="text/html" Language="C#" %>
<script runat="Server">
void objBtn_Click(Object sender, EventArgs e) {
  if(FormsAuthentication.Authenticate(txtUsr.Text,txtPass.Text)){
    FormsAuthentication.RedirectFromLoginPage(txtUsr.Text,false);
  }else{
    objLbl.Text="正しいユーザーID、パスワードを入力してください";
  }
}
</script>
<html>
<head>
  <title>フォーム認証ログイン</title>
</head>
<body>
  <form runat="Server">
  <center>
    <h1>フォーム認証ログイン</h1>
    <hr />
    <b>ユーザーID:</b>
    <asp:TextBox id="txtUsr" runat="Server" Columns="12" /><br />
    <b>パスワード:</b>
    <asp:TextBox id="txtPass" runat="Server" Columns="11" TextMode="Password" />
    <br />
    <asp:Button id="objBtn" runat="Server" Text="ログイン" OnClick="objBtn_Click" /><br />
    <asp:Label id="objLbl" runat="Server" ForeColor="Red" />
  </center>
  </form>
</body>
</html>
ログイン画面のページ(login_cs.aspx)
 
<%@ Page ContentType="text/html" Language="VB" %>
<script runat="Server">
Sub objBtn_Click(sender As Object, e As EventArgs)
  If FormsAuthentication.Authenticate(txtUsr.Text,txtPass.Text) Then
    FormsAuthentication.RedirectFromLoginPage(txtUsr.Text,False)
  Else
    objLbl.Text="正しいユーザーID、パスワードを入力してください"
  End If
End Sub
</script>
<html>
<head>
  <title>フォーム認証ログイン</title>
</head>
<body>
  <form runat="Server">
  <center>
    <h1>フォーム認証ログイン</h1>
    <hr />
    <b>ユーザーID:</b>
    <asp:TextBox id="txtUsr" runat="Server" Columns="12" /><br />
    <b>パスワード:</b>
    <asp:TextBox id="txtPass" runat="Server" Columns="11" TextMode="Password" />
    <br />
    <asp:Button id="objBtn" runat="Server" Text="ログイン" OnClick="objBtn_Click" /><br />
    <asp:Label id="objLbl" runat="Server" ForeColor="Red" />
  </center>
  </form>
</body>
</html>
ログイン画面のページ(login_vb.aspx)

 ログイン画面で必ず記述しなければならないのは、以下の2点だけだ。

(1)ユーザーのアクセス可否を判定する

 web.configに記述されたユーザー情報を基に認証を行う場合、ASP.NETにはシンプルなメソッドが用意されている。それが、FormsAuthenticationクラス(System.Web.Security名前空間)のAuthenticateメソッドだ。パラメータとしてユーザー名とパスワードを渡しさえすれば、あとは自動的に認証判定を行い、認証が認められる場合にはTrueを、認められない場合にはFalseを返す。

(2)認証クッキーを発行する

 認証が認められた後の挙動を制御するのが、FormsAuthenticationクラス(System.Web.Security名前空間)のRedirectFromLoginPageメソッドである。フォーム認証によるログイン画面には通常、RedirectFromLoginPageメソッドの記述がなければならない(ただし、ログイン後の挙動をカスタマイズしたい場合には、必ずしもこの限りではない。この方法については別稿にて紹介する)。第1パラメータにはクッキーに保存するユーザー名を、第2引数にはクッキーを永続化するかどうかを示すブール値を指定する。

 第2パラメータにTrueを設定した場合には、認証クッキーはクライアントがブラウザを閉じた後も永続的に保持される。つまり、次のアクセスに際しては認証行為が必要ない。さほど厳密ではない認証(例えば、「パーソナライゼ―ション」のための認証など)において、認証情報の永続化は「ユーザーの手間を省く」有効な手段である。もちろん、厳密な認証を要する局面では、永続化機能は有効にするべきではない。

 以上で、フォーム認証の準備は完了だ。「/auth」フォルダ配下の任意の.aspxファイルにアクセスすると、自動的にログイン・ページにリダイレクトされることを確認してほしい。

ログイン・ページ

認証が成功した場合には、sample.aspxを表示

認証に失敗した場合には、エラー・メッセージを表示

 ただし、フォーム認証が認識する対象は、ASP.NETに関連付けられたファイル(拡張子)に限定されるので注意すること。例えば、「.html」や「.txt」などの拡張子のファイルにアクセスしても、ログイン・ページは有効にならない。これを回避する方法については、別稿「TIPS:[ASP.NET].htmlや.pdfファイルをフォーム認証やロギングの対象にするには?」にて紹介している。End of Article

カテゴリ:Webフォーム 処理対象:構成ファイル
使用キーワード:<authentication>要素
使用キーワード:<authorization>要素
使用ライブラリ:FormsAuthenticationクラス(System.Web.Security名前空間)
関連TIPS:[ASP.NET].htmlや.pdfファイルをフォーム認証やロギングの対象にするには?
 
この記事と関連性の高い別の.NET TIPS
[ASP.NET]フォーム認証のユーザー管理をXMLファイルで行うには?
[ASP.NET]フォーム認証のユーザー管理をデータベース・サーバで行うには?
[ASP.NET AJAX]クライアントサイド・スクリプトからカスタムの認証機能を利用するには?
[ASP.NET]認証後のページでカスタムのユーザー情報を引用するには?
[ASP.NET]構成ファイルの適用範囲を限定するには?
このリストは、(株)デジタルアドバンテージが開発した
自動関連記事探索システム Jigsaw(ジグソー) により自動抽出したものです。
generated by

「.NET TIPS」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間