ASP.NET MVC における、フォーム認証の実装例を掲載します。 今回は ASP.NET MVC 4 で実装しています…が、 ASP.NET MVC 3 でも似たような実装になるかと思います。
目次
概要
IIS は 「匿名認証」 で動作させ、IIS 上で動く ASP.NET アプリケーション で 「フォーム認証」 を実装します。 動作イメージ は以下のようなものを想定します。 図中、「フォーム認証」から「サーバー処理」に至るまでが本記事で対象とする実装範囲です。
作成、編集するファイルは以下の通りです。 認証、承認の方法は web.config で設定し、 認証の実処理は UserController.cs で実現します。 フォーム認証の画面は Login.cshtml になります。
web.config の 設定
以下のサンプルでは、「認証」を「Form 認証」を用いて /User/Login で実行し、 「承認」を「ログイン済みユーザーはすべてのリソースにアクセス可能(=未ログインユーザーはすべてのリソースに対してアクセス拒否)」として行います。
/ web.config
<configuration> <system.web> <!-- 認証の設定 --> <authentication mode="Forms"> <forms loginUrl="/User/Login"/> </authentication> <!-- 承認の設定 --> <authorization> <deny users="?"/> </authorization> </system.web> </configuration>
ログイン モデル の 作成
/ Models / UserModel.cs
namespace MvcApplication.Models { public class LoginModel { public string Id { get; set; } public string Password { get; set; } public bool RememberMe { get; set; } } }
ログイン ビュー の 作成
/ Views / User / Login.cshtml
@model MvcApplication.Models.LoginModel @{ ViewBag.Title = "Login"; } <h2>Login</h2> @Html.ValidationSummary() @using (@Html.BeginForm()) { <table> <tr> <th>ユーザーID</th> <td>@Html.TextBoxFor(model => model.Id)</td> </tr> <tr> <th>パスワード</th> <td>@Html.PasswordFor(model => model.Password)</td> </tr> <tr> <td colspan="2"> <label> @Html.CheckBoxFor(model => model.RememberMe) ログインしたままにする。 </label> </td> </tr> <tr> <td colspan="2" style="text-align:right;"> <input type="submit" value="ログイン" /> <td> </tr> </table> }
ログイン 処理 の 実装
以下の サンプルコード において、認証処理は固定文字列で行っています。 この部分を データベース から取ってくるなり、ファイル から取ってくるなりすることで、好きな認証方法が実現できます。
蛇足かもしれませんが…ログイン処理に失敗した場合、エラーメッセージは「ユーザー名またはパスワードが異なります」とします。 「ユーザー名が異なります」や「パスワードが異なります」のような具体的メッセージにすると、不正アクセスを試みているユーザーにヒントを与えることになるためです。
/ Controllers / UserController.cs
namespace MvcApplication.Controllers { using System.Web.Mvc; using System.Web.Security; using Models; public class UserController : Controller { // // GET: /User/Login [HttpGet] public ActionResult Login() { return this.View(); } // // POST: /User/Login [HttpPost] public ActionResult Login(LoginModel model, string returnUrl) { if (model.Id == "hoge" && model.Password == "hoge") { // ユーザー認証 成功 FormsAuthentication.SetAuthCookie(model.Id, model.RememberMe); return this.Redirect(returnUrl); } else { // ユーザー認証 失敗 this.ModelState.AddModelError(string.Empty, "指定されたユーザー名またはパスワードが正しくありません。"); return this.View(model); } } } }
[おまけ] ログアウト
/Home/Index において、 ログアウト ボタンを設置し、ログアウト できるようにします。 ログアウト の実処理は UserController に追記することで行います。
/ Views / Home / Index.cshtml
@{ ViewBag.Title = "Index"; } <h2>Index</h2> @using (Html.BeginForm("Logout", "User", FormMethod.Post)) { <input type="submit" value="ログアウト" /> }
/ Controllers / UserController.cs
// // POST: /User/Logout [HttpPost] public ActionResult Logout() { FormsAuthentication.SignOut(); return this.Redirect("/"); }
今回、以下のサイトを参考にしました。
- IPA - IPA セキュア・プログラミング講座: Webアプリケーション編
- IPA ISEC - 第2章 アクセス制御 ユーザ認証
- IPA ISEC - 第2章 アクセス制御 アクセス認可
- ITメディア エンタープライズ - 認証と認可の違い
- MSDN - authentication 要素 (ASP.NET 設定スキーマ)
- MSDN - authentication の forms 要素 (ASP.NET 設定スキーマ)
- MSDN - authorization 要素 (ASP.NET 設定スキーマ)
- MSDN - authorization の allow 要素 (ASP.NET 設定スキーマ)
- MSDN - authorization の deny 要素 (ASP.NET 設定スキーマ)
- ASP.NETでRDBMSやテキストファイルを使って認証する
最後に… このブログに興味を持っていただけた方は、 ぜひ 「Facebookページ に いいね!」または 「Twitter の フォロー」 お願いします!!