【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:
というパスに転送される.このパスはこれまで見てきたものと同様のURLルーティングに従って処理されるため,
このアプリケーションはポート番号
/Admin/LoginAdmin
という名前のコントローラーを備えている必要がある.本節ではこのコントローラーの作成を行う(_).
管理者としてログインする機能は一般のユーザーが直接アクセスする必要があるものではないため,ここでは
アドレスバーにURLを入力することで直接遷移して使用することにする.ログイン後はすべてのページに「ログアウト」のためのボタンが表示されるようにし,
いつでもログアウトができるようにする.またアクセス拒否の場合のエラーページの表示はAcccessDenied
というアクションで対応することにする.
このコントローラーを作成する前に,ログイン画面でユーザー名とパスワードの入力に使うための ビュー専用のモデルクラス を用意しておこう.
プロジェクト内の Models フォルダを右クリックし,「追加」→「クラス」をクリックする.作成するクラス名を訊かれるので
LoginUserInfo
(.csは省略可能)と入力して「追加」ボタンをクリックする.すると空のクラス定義が作られるので_の定義を書き込もう.
|
|
この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 を使用する限りは,アプリケーション側の独自のモデルクラスに「パスワード」などという認証情報を持たせる必要は全くない .
もう一度強調するが,データベースに平文のパスワードを直接保存するようなアプリケーションは作ってはならない. 今後ウェブアプリを自由製作する時間を設けるが,そのときにこのようなデータモデルの設計をしてしまわないように注意すること.