情報応用演習Ⅰ(2024)

【T8b】ASP.NET Core Identity の基礎(6/9)

プロジェクトタイプ(注意: 本文参照)
プロジェクト名T8b
ソリューション名PIT8
注意
  • 本ページの作業内容は 前のページまでの続き になっていることに注意せよ.
    • 先に前のページまでをすべて読み,指示されている作業を済ませてから本ページを読むこと.
    • プロジェクトの作成作業については準備作業を参照せよ.

8b-6. 認証に関する基礎設計

ここまでで管理者ユーザーは作られたが,まだ ログイン画面 を作成していない. 今回はAdminという名前のコントローラーでログインやログアウトといった処理を行うことを前提としている. このことはリスト8b-4-2の Program.cs の26~31行目にすでに現れている.当該の部分を_に抜粋する.

.ConfigureApplicationCookie()メソッドは, Cookie(くっきー)と呼ばれる仕組みを使った認証情報の保存を有効化するメソッドであるが, _の3~5行目で設定しているのがログイン,ログアウト用のページのパスである.例えばログインが必要なときは3行目の.LoginPathに設定している http://localhost:ポート番号/Admin/Loginというパスに転送される.このパスはこれまで見てきたものと同様のURLルーティングに従って処理されるため, このアプリケーションはAdminという名前のコントローラーを備えている必要がある.本節ではこのコントローラーの作成を行う(_).

Adminコントローラー周りの画面イメージと画面遷移

管理者としてログインする機能は一般のユーザーが直接アクセスする必要があるものではないため,ここでは アドレスバーにURLを入力することで直接遷移して使用することにする.ログイン後はすべてのページに「ログアウト」のためのボタンが表示されるようにし, いつでもログアウトができるようにする.またアクセス拒否の場合のエラーページの表示はAcccessDeniedというアクションで対応することにする.

このコントローラーを作成する前に,ログイン画面でユーザー名とパスワードの入力に使うための ビュー専用のモデルクラス を用意しておこう. プロジェクト内の Models フォルダを右クリックし,「追加」→「クラス」をクリックする.作成するクラス名を訊かれるので LoginUserInfo(.csは省略可能)と入力して「追加」ボタンをクリックする.すると空のクラス定義が作られるので_の定義を書き込もう.

ログイン画面のためのモデルクラス
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
using System.ComponentModel.DataAnnotations; // 追記

namespace T8b.Models
{
    // ログイン画面のためのモデルクラス
    public class LoginUserInfo
    {
        [Display(Name = "ユーザー名")]
        public string Username { get; set; } = "";

        [Display(Name = "パスワード")]
        [DataType(DataType.Password)]
        public string Password { get; set; } = "";
    }
}

このLoginUserInfoクラスのPasswordプロパティには,[DataType]属性を用いてそれがパスワードであることを意味するDataType.Passwordを指定してる. これによって,このプロパティに対する入力欄では入力値が隠されるようになる(「●●●●●」のような表示になる).

ここでひとつ厳重に注意しておくことがある.ASP.NET Core に限らず認証を行うアプリケーションでは「ユーザー」に相当する エンティティ(≒テーブル)に平文のパスワードを直接保存してはならない.これは現実のシステムでも稀にある誤った設計の一つである.

_のモデルクラスはログイン画面における情報のやり取りに使うだけのクラスであって, 入力したユーザー名とパスワードをデータベースに保存するといった目的のものではない.つまりこのクラスはデータコンテキストクラスには登録しないし, このクラスに対応するテーブルも作らない .いかなるウェブアプリであっても, データベース上にパスワードを読める形で保存する ,といったことは決して行ってはならない. データベースにはユーザーが設定したパスワードを 一定の手順で変換したデータ のみを保存するのが一般的である.この変換には 不可逆変換済みのデータから元のデータを推定することが 不可能である変換方法 が用いられる.この一方通行な変換のため, ハッシュ関数 と呼ばれる種類の変換手段が用いられることが多い.ユーザーを識別する際はユーザーが送信したパスワードを同じ方法で変換し, その結果がデータベースに保存された変換済みデータと一致するかどうかを検証することで認証を行う. このような方法をとる理由の一つは認証情報の機密性を保つためである.アプリケーションやそれを収容するサーバのセキュリティが 破られてデータベースの中身を盗まれたとしても,この方法であればデータベースには変換済みのデータしかないためそのユーザーが用いていた パスワードが漏洩することを防止することができる.ASP.NET Core Identity でも内部的にこのような認証情報の管理を行っている.

「ユーザー」テーブルには平文のパスワードは直接的には保存されていない

実際,ASP.NET Core Identity のデフォルトの「ユーザー」に対応するモデルクラスである IdentityUserクラス (データベース上は前述のAspNetUsersテーブルに対応するクラス)には, .PasswordHashというプロパティはあるが,Passwordというプロパティは存在しない.試しにpgAdminで現状のAspNetUsersテーブルの内容を表示させてみよう._を見ると分かるように, AspNetUsersテーブルには現在のところ,adminユーザーに対応するレコードのみが唯一存在しているはずであるが, そのPasswordHash列の値を見ると,このユーザーのパスワードである"p@55W0rD"という文字列は含まれていないはずである. またこのテーブルのほかのどの列をみても当該の文字列は見つからないはずである.これは ASP.NET Core Identity が前述したような パスワードの管理方法を採っているためである.

このため認証の仕組みとして ASP.NET Core Identity を使用する限りは,アプリケーション側の独自のモデルクラスに「パスワード」などという認証情報を持たせる必要は全くない

もう一度強調するが,データベースに平文のパスワードを直接保存するようなアプリケーションは作ってはならない. 今後ウェブアプリを自由製作する時間を設けるが,そのときにこのようなデータモデルの設計をしてしまわないように注意すること.

Last updated on 2024-06-10
Published on 2024-06-10

Powered by Hugo. Theme by TechDoc. Designed by Thingsym.