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 の フォロー」 お願いします!!