フォーム認証を利用したWebアプリケーションでは、独自のログインページと認証プロセスを用いて柔軟な資格情報の検証が可能だ。
前回では、Windows認証を実装したWebアプリケーションである「winauth」を作成しながら、そのプログラムについて解説した。今回はwinauthアプリケーションとまったく同じ機能のアプリケーションを、フォーム認証を使って実装していくことにしよう。アプリケーションの名前は「formauth」と名付けることにする。
formauthアプリケーションは以下に示す4つのファイルから構成されている。
formauthアプリケーションのダウンロード(formauth.zip)
アプリケーション実行時のそれぞれの画面は以下のようなものだ。
このうちdefault.aspxとadmin.aspxは前回のwinauthアプリケーションとほぼ同じものを使用しているので(ただしdefault.aspxには[サインアウト]ボタンが追加されている)、以降の解説は設定ファイルであるweb.configと、ログイン・フォームであるlogin.aspxを中心に進める。
■web.configでの設定
まずはweb.configから見ていこう(リスト19.1)。authentication要素で認証モード(Forms)を指定し、authorization要素でURL認定のルールが指定されているところはWindows認証と同じだが、フォーム認証にまつわるパラメータを設定するforms要素と、資格情報を記述するcredentials要素が追加されている。
<configuration>
<system.web>
<authentication mode="Forms">
<forms name="formauth" loginUrl="login.aspx"
protection="All" path="/" timeout="30">
<credentials passwordFormat="Clear">
<user name="user1" password="hoge" />
<user name="user2" password="himitsu" />
</credentials>
</forms>
</authentication>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
forms要素の属性値として指定されるフォーム認証のパラメータは、ログイン・フォームへのURLを示すloginUrl属性を除いて、すべて認証チケットとなるクッキーのために使われるものである(表19.1)。
フォーム認証では、いったん認証されると認証チケットと呼ばれる資格情報がクッキーとしてクライアントへ送信される。クライアントはこのクッキーを送信することで認証済みであることを示し、アプリケーションへアクセスすることができる。もし認証チケットを示さずにアクセスを試みれば、どのページへアクセスしようとしても、loginUrl属性で指定されたページへとリダイレクトされることになる。
属性 | 目的 |
---|---|
name | アプリケーション名。認証チケットを保存するクッキーの名前に使われる |
loginUrl | ログイン・フォームのURL |
protection | クッキーの暗号化と検証の有無を指定 |
timeout | チケットの有効期間(単位:分) |
path | クッキーのパス |
表19.1 forms要素の属性 |
form要素中にあるcredentials要素の子要素には、以下のようにして、ログイン・フォームでの認証に使われる資格情報を記述できる。ここではcredentials要素のpasswordFormat属性に“Clear”を指定しているので、パスワードを平文で指定しているが、“MD5”または“SHA1”を指定することで、ハッシュ値を指定することも可能だ。ただし、ハッシュ値を求めるツールなどは用意されていないので、必要ならば自作しなければならない。
<user name="ユーザー名" password="パスワード" />
こうしてフォーム認証用の資格情報をweb.configに記録しておけば、別途パスワードファイルを用意する必要がなくなり、フレームワークから提供されるヘルパ・メソッドを利用して認証を行えるため非常に手軽だ。しかし、この方法ではユーザーが所属するロールを記録できないなどデメリットが少なくない。そこで、これは簡易的な認証手段と割り切り、実際には資格情報の管理を独自に実装すべきだろう。これについて詳しくは後述するformauth2アプリケーションで解説する。
■ログイン・フォーム
認証チケットを持たないユーザーがリダイレクトされてくるログイン・フォームのページがリスト19.2に示すlogin.aspxである。
<%@ Page Language="C#" %>
<html>
<head>
<script runat="server">
void login_Click(object sender, EventArgs e) {
if (FormsAuthentication.Authenticate(tbUsername.Text, tbPassword.Text)) {
FormsAuthentication.RedirectFromLoginPage(tbUsername.Text,
persist.Checked);
} else {
Message.Text = "失敗しました。パスワードを確認してください";
}
}
</script>
</head>
<body>
<form runat="server">
<p>UserName : <asp:TextBox id="tbUsername" runat="server" /></p>
<p>Password : <asp:TextBox id="tbPassword" TextMode="Password" runat="server" /></p>
<p>
<asp:CheckBox id="persist"
Text="認証情報を記憶する" runat="server"/>
<asp:Button id="login" Text="ログイン"
OnClick="login_Click" runat="server" />
</p>
<p><asp:Label id="Message" ForeColor="red" runat="server" /></p>
</form>
</body>
</html>
恐らく予想よりもかなり単純に思えるはずだ。ログイン・フォームでは、入力されたユーザー名とパスワードから認証を行い、成功したら認証チケットを発行して、元々アクセスされていたページへとリダイレクトする作業を行う。この作業は、以下のように2つのメソッドを呼び出すだけで実装できる。
if (FormsAuthentication.Authenticate(tbUsername.Text, tbPassword.Text)) {
FormsAuthentication.RedirectFromLoginPage(tbUsername.Text,
persist.Checked);
}
Authenticateメソッドは指定された資格情報をweb.configに登録された情報を使って認証し、成功すればtrue、失敗すればfalseを戻す。一方、RedirectFromLoginPageメソッドは、web.configに指定されたパラメータに従って認証チケット(クッキー)を発行し、クエリー文字列のReturnUrlキー(ログイン・フォームへ導かれる前のURLを値に持つ)へリダイレクトするメソッドである。これらのヘルパ・メソッドは、いずれもSystem.Web.Security名前空間に宣言されているFormsAuthenticationクラスのメソッドとして実装されている。
RedirectFromLoginPageメソッドの第2パラメータにfalseを指定したとき、認証チケットはセッション・クッキーとして作成されるため、セッションを終了すると消えてしまうが、trueを指定してパーマネント・クッキーとして作成することもできる。この場合、50年という非常に長い有効期限を持つクッキーがクライアントのディスク上に作成されるため、ブラウザをいったん終了しても、ログイン・フォームへリダイレクトされることなく再びアプリケーションへとアクセスできるようになる。サンプルformauthでは、ログイン・フォームで[認証情報を記憶する」チェック・ボックスがチェックされていればパーマネント・クッキーが作成されるようにしてある。
パーマネント・クッキーを利用すれば、資格情報の入力をスキップできるので便利ではあるが、このままでは別の資格情報(別のユーザー)でログインできなくなってしまうので、default.aspxにはクッキーを削除するための[サインアウト]ボタンを追加している。このボタンをクリックすると、以下のコードによってクッキーが削除され、ログイン・フォームへとリダイレクトされる。
void signout_Click(object sender, EventArgs e) {
FormsAuthentication.SignOut();
Response.Redirect("login.aspx");
}
Copyright© Digital Advantage Corp. All Rights Reserved.