ASP.NET MVC で フォーム認証 の実装方法

0 件のコメント

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("/");
        }

今回、以下のサイトを参考にしました。