「[[Open棟梁 wiki>https://opentouryo.osscons.jp]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>汎用認証サイト(Multi-purpose Authentication Site)]]

*目次 [#j24adbab]
#contents

*概要 [#i84718cb]
[[汎用認証サイト(Multi-purpose Authentication Site)]]の独自仕様部分について説明する。

*Idp仕様 [#f550c2de]
**概要 [#p07e3d3b]
Idpの仕様については概ね、ASP.NET Identityに準拠。

ASP.NET Identity側の仕様については、「[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]」を参照。

**カスタマイズ・ポイント [#n3b708da]
***マルチテナント化スイッチ [#j6087e30]
以下のスイッチで大きな動作変更が可能。

***RequireUniqueEmailスイッチ [#gbd5af06]
詳しくは「[[汎用認証サイトのコンフィギュレーション]]」を参照のこと。

***[[RequireUniqueEmailスイッチ>汎用認証サイトのコンフィギュレーション#g813e54f]] [#gbd5af06]

以下のように、主に[[サインアップ・プロセス>#rc86b3dc]]に影響を与える。

-RequireUniqueEmail : true
--UserName = E-mailアドレス
--インターネット環境の標準の実装はこちら。
--E-mailアドレスでサインアップし、~
直ちにE-mailアドレスの確認(E-mail confirmation)を行う。
--E-mailアドレスでサインアップするため、直ちにE-mailアドレスの確認~
(E-mail confirmation)を行うため、サインアップ・プロセスは複雑化する。

-RequireUniqueEmail : false
--UserName = 任意文字列
--ユーザストアを管理者が準備するエンプラ向き実装はこちら。

--E-mailアドレスの確認(E-mail confirmation)は不要
---サインアップで、E-mailアドレスが提供されないので、~
E-mailアドレスの確認(E-mail confirmation)が実質的に不可能。
--サインアップで、E-mailアドレスが提供されないので、~
サインアップ・プロセスは、UserName=メアドよりシンプルになる。~
しかし、E-mailアドレスの確認(E-mail confirmation)が実質的に不可能。
---サインアップ画面を提供せず、管理者がアカウント(E-mailアドレス)を準備する。
---若しくは、サインアップ画面を提供し、"ユーザ名 @ サイトのドメイン"でメアドを準備するなどとする。
---若しくは、UserNameとE-mailアドレスの入力が可能なサインアップ画面を提供したり、
---"ユーザ名@サイトのドメイン"でE-mailアドレスを準備するなどとする。

--外部ログインの場合
---サインアップ・サインインも可能ではある。
---しかし、基本的には"外部ログイン = OFF"だと考える。
-その他、
--[[ユーザ名変更>#o0947cd8]]
--[[外部ログイン>#w534c815]]

***デバッグ用スイッチ [#s79a0f6c]
-切替方法
--スイッチのON/OFF
--ユーザストアへのアクセスにメモリ・プロバイダを指定している場合。
>の動作にも影響を与える。

-動作
--デバッグ時:通知プロバイダを使用しない
--本番時:通知プロバイダを使用する

**利用するサービス [#a92c7f68]
***[[外部ログイン>#w534c815]] [#saead825]
-Microsoft
-Google
-Facebook

***[[オンライン決済サービス>汎用認証サイト(Multi-purpose Authentication Site)#qf3fddd8]] [#mf9d3a00]
-Stripe
-PAY.JP

***[[通知プロバイダ>汎用認証サイト(Multi-purpose Authentication Site)#j3aea225]] [#i20fcfb1]
-SMTP
-SMS (Twilio)

**ユーザ・アカウント [#xa20a1e2]
***主要属性 [#b725e4d1]
-UserId = GUID

-UserNameはスイッチ次第
-[[UserNameはスイッチ次第>#gbd5af06]]
--基本は、E-mailアドレス
--スイッチ変更により、任意の文字列を使用可能。

-Passwordの強度は[[下記の設定>#x111a0c2]]に従う。
-Password
--Passwordの強度は[[コチラの設定>汎用認証サイトのコンフィギュレーション#pca79851]]に従う。
--当然、[[ライブラリにて適切にハッシュ化>https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Models/ASPNETIdentity/Manager/CustomPasswordHasher.cs]]されてからUserStoreに保存される。

-その他
--[[スキーマ>#e472fd55]]を参照。

***永続化 [#d378ad48]
-[[EntityFramework>https://techinfoofmicrosofttech.osscons.jp/index.php?Entity%20Framework]]をキャンセルしUserStoreクラスで実装。
-DBMSはSQL Server or PostgreSQLを使用。
-Dapperを使用してデータアクセスを実装。
-[[UserStoreTypeの設定>汎用認証サイトのコンフィギュレーション#y8c5ea41]]で、UserStoreクラスの使用するデータストアを変更可能。
--データストアは、メモリとRDBMSをサポート(NoSQLやLDAPのサポートも可能)
--RDBMSへのデータアクセスは、Dapperを使用して実装している。

**スキーマ [#e472fd55]

***DDL [#ge5c13dd]
Githubをポイント予定
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/tree/develop/root/files/resource/Sql

***編集処理 [#hfcc91ec]
-管理画面でユーザ・ロールの属性値の編集が可能
-マルチテナント化している場合、テナント・データのみが対象になる。
-アカウント編集処理
--非定型データを使用すればスキーマ変更は不要。
--[[設定>汎用認証サイトのコンフィギュレーション#b233454c]]によってロックダウン可能。
--編集可能なアカウント属性については[[こちら>#sc966644]]。

-ユーザ管理
--管理者アカウントによるユーザ管理
--管理者アカウントとマルチテナント
---マルチテナントの場合:サインアップ・ユーザ
---マルチテナントでない場合:システム管理者
--編集可能な属性については[[こちら>#sc966644]]。
-ユーザ・ロール編集処理
--管理画面でユーザ・ロールのCRU(属性編集)Dが可能
--管理画面についての詳細は[[こちら>#ga313890]]。

-ロール管理
--管理者アカウントによるユーザ管理
--管理者アカウントとマルチテナント
---マルチテナントの場合:サインアップ・ユーザ
---マルチテナントでない場合:システム管理者

**サインアップ・サインイン [#oe564461]

***サインアップとE-mailアドレス確認 [#rc86b3dc]
-E-mailアドレスの確認(E-mail confirmation)は、~
初回サインアップ後のレコードに対して行なう。
UserName = E-mailアドレス の場合、

-E-mailアドレスの確認(E-mail confirmation)をしなかった場合、~
--サインアップをしようとすると、サインアップ済みの旨が表示される。
--E-mailアドレス確認は、初回サインアップ後のレコード(ユーザID・PWD)に対して行なう。
-E-mailアドレスの確認(E-mail confirmation)は、初回サインアップ(レコード生成)後のアカウント(レコード)に対して行なう。

-初回サインアップ後、
-初回サインアップ(レコード生成)後に、E-mailアドレスの確認(E-mail confirmation)をしなかった場合、~
--サインアップをしようとすると、レコードを再生成後、E-mailアドレスの確認(E-mail confirmation)が再送される。
--サインインをしようとすると、E-mailアドレスの確認(E-mail confirmation)が再送される。

-初回サインアップ(レコード生成)後、
--E-mailアドレス確認のメールをロストした場合、~
サインインを繰り返せば、再び、E-mailアドレス確認メールは飛ぶ。
--パスワードを失念した場合、[[パスワード・リセット>#f88a0fb5]]を行えばサインアップできる。
---サインアップを繰り返せば、再び、E-mailアドレス確認メールは飛ぶ(レコードが再生成されるのでパスワードも変更される)。
---サインインを繰り返せば、再び、E-mailアドレス確認メールは飛ぶ(レコードが再生成されないのでパスワードは古いまま)。

--パスワードを失念した場合、
---上記の「サインアップを繰り返す」を行えばサインアップできる。
---若しくは、[[パスワード・リセット>#t06f7341]]を行えばサインアップできる。

***サインイン・サインアウト [#l4470148]
通常通り。
-通常通りサインアップする。
-[[Passwordの強度>#b725e4d1]]を満たさない場合、エラーとなることを確認する。

***パスワード・リセット [#f88a0fb5]
-パスワードを失念した場合
-サインアップ時のパスワードを失念した場合にも使用可能。

**アカウント編集 [#sc966644]
***ユーザ名 [#o0947cd8]
-アカウント編集でユーザ名を変更
-UserName = E-mailアドレス の場合、~
E-mailアドレスの確認(E-mail confirmation)が必要。

***パスワード [#u4227d89]
-変更
-設定([[外部ログイン>#w534c815]]後、ローカル・ログオンを可能にする場合)
-アカウント編集でパスワードを設定・変更
--変更
--設定([[外部ログイン>#w534c815]]後、ローカル・ログオンを可能にする場合)

***[[外部ログイン>#w534c815]] [#z8a5ebd4]
[[外部ログイン>#w534c815]]の一覧表示と追加・削除
-[[Passwordの強度>#b725e4d1]]を満たさない場合、エラーとなることを確認する。

***電話番号 [#p3aec882]
-編集(設定・削除)が可能
-[[通知プロバイダのSMS>汎用認証サイト(Multi-purpose Authentication Site)#j3aea225]]を使用。
***E-mailアドレス [#haeb62dc]
-アカウント編集でE-mailアドレスを設定・削除
-UserName = E-mailアドレス の場合に表示される。

***[[二要素認証 (2FA) >#w7ba6fad]] [#b2ceb7bb]
[[二要素認証 (2FA) >#w7ba6fad]]のON/OFF
-E-mailアドレスの確認(E-mail confirmation)が必要。
--リンクを実行しない場合、E-mailアドレス設定が正常終了しない。
--リンクを実行した場合、E-mailアドレス設定が正常終了する。

***[[オンライン決済サービス>汎用認証サイト(Multi-purpose Authentication Site)#qf3fddd8]] [#hb5e1c33]
クレジット・カードの登録
***電話番号 [#p3aec882]
-アカウント編集で電話番号を設定・削除
-[[通知プロバイダのSMS>汎用認証サイト(Multi-purpose Authentication Site)#j3aea225]]で通知を行い、受信したコードを入力する。
--誤ったコードを入力した場合、電話番号設定が正常終了しない。
--正しいコードを入力した場合、電話番号設定が正常終了する。

***, etc. (任意項目を追加可能) [#z9bb4735]
***[[2要素認証(2FA)>#w7ba6fad]] [#b2ceb7bb]
-アカウント編集で[[2要素認証(2FA)>#w7ba6fad]]をON/OFFする。
-[[2要素認証(2FA)>#w7ba6fad]]のプロセスについては[[後述>#w7ba6fad]]する。

**二要素認証 [#w7ba6fad]
***[[外部ログイン>#w534c815]] [#z8a5ebd4]
[[外部ログイン>#w534c815]]の一覧表示と追加・削除

***有効化 [#q5586e1b]
アカウント編集にて有効化
***[[オンライン決済サービス>汎用認証サイト(Multi-purpose Authentication Site)#qf3fddd8]] [#hb5e1c33]
-[[オンライン決済サービスとしては、StripeとPAY.JPを *.config で設定可能>汎用認証サイトのコンフィギュレーション#p10405d7]]。
-設定が有効な場合、クレジット・カード情報などの支払い元情報が設定できる。
-登録したクレジット・カード情報を利用してオンライン決済サービスを使用する。
-[[Debugモード>汎用認証サイトのコンフィギュレーション#v443d7eb]]の場合、オンライン決済サービスで決済されることを確認する。

***他のブラウザでテスト [#red3542c]
-有効化した後は、他のブラウザでテストする。
-二要素認証はCookieを使用しているため、ブラウザ単位で行う。
***属性データ(非定型データ) [#z9bb4735]
-属性データ(非定型データ)をメンテナンスする。
-JSON形式での情報格納を想定しているので、スキーマ(DDL)変更は不要。

**運用 [#q853018f]
***OAuth2データ [#icfa3463]
ユーザ毎に、
-client_id
-client_secret
-redirect_uri(code)
-redirect_uri(token)

***アカウント・ロックアウト [#tdca397b]
指定回数、ログインをミスすると、指定時間ロックアウトされる。
のデータを設定し、

OAuth2アクセストークンを取得可能。

**運用系機能 [#q853018f]
***パスワード・リセット [#t06f7341]
-通常のパスワード・リセットのシナリオ。
--パスワードを失念した場合、パスワード・リセットを行う。

-例外的に以下のシナリオで使用する。
--初回サインアップ時のパスワードを失念した場合のシナリオ。
--[[外部ログイン>#w534c815]]後、ローカル・ログオンを可能にするシナリオ。

-[[Passwordの強度>#b725e4d1]]を満たさない場合、エラーとなることを確認する。

**セキュリティ強化機能 [#df6f9e87]
***アカウント・ロックアウト [#tdca397b]
[[指定回数、ログインをミスすると、指定時間ロックアウトされる。>汎用認証サイトのコンフィギュレーション#p523874d]]

***SecurityStamp [#vbd67fbf]
-アカウント編集後にサインアウトされる。
-アカウント編集(ユーザ属性の変更)後のアクセスがサインアウトされる。
-アカウント編集後にサインアウト・サインインする実装になっている理由はコレ。

***2要素認証 [#w7ba6fad]
-アカウント編集で2要素認証をONにする。

-別のブラウザからログイン試行を行う~
(2要素認証ではCookieでブラウザを記憶するため)。

-すると通知プロバイダを選択したコードを送信が行われる。

-選択した通知プロバイダで通知を行い、受信したコードを入力する。
--誤ったコードを入力した場合、2要素認証が正常終了しない。
--受信したコードを入力して2要素認証が正常終了する。

-.NET Core版では、TOTPの2FAがサポートされている。

**その他、追加の対応 [#fd41fc42]
***[[FIDO2.0対応]] [#a4e5d429]
***[[GDPR対策]] [#w97af74f]

*外部ログイン仕様 [#w534c815]

**概要 [#x9ecc92c]
概ね、[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]に準拠。

[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]側の仕様については、「[[ASP.NET Identityの外部ログイン>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity%E3%81%AE%E5%A4%96%E9%83%A8%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3]]」を参照。
-[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]側の仕様については、~
「[[ASP.NET Identityの外部ログイン>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity%E3%81%AE%E5%A4%96%E9%83%A8%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3]]」を参照。

-サインアップ・サインインも可能。
-基本的には、[[UserName = E-mailアドレス>#gbd5af06]]

**カスタマイズ・ポイント [#n861c0bc]
外部ログイン処理の仕様について。

***外部ログイン・サービス [#m1ac1110]
-Microsoft
-Google
-Facebook
-Twitter
***外部ログイン設定 [#m1ac1110]
[[外部ログインと、外部ログイン・サービスを設定する。>汎用認証サイトのコンフィギュレーション#uc4663b1]]

-[[RequireUniqueEmailスイッチ>#gbd5af06]]
--[[UserName = E-mailアドレス>#gbd5af06]]で動作する。
--[[UserName ≠ E-mailアドレス>#gbd5af06]]での外部ログインとの親和性は低い。
---通常、サインアップ画面を提供せず、管理者がアカウント(E-mailアドレス)を準備する。
---殆どのIdPではE-mailを使用しており、オプションで使用しているUserNameがIdP間で一致していないことが多いため。
---IdP間を跨ぐ場合、UserNameの一意性は保証されないので、結局、E-mailアドレス確認(E-mail confirmation)されたE-mailに頼る必要がある。

-XsrfKey~
XSRF(=CSRF)を防ぐためのstateパラメタの生成に使用される。

-外部ログイン・サービス
--Microsoft
--Google
--Facebook
--Twitter

***外部ログインでサインアップ [#cd8169dc]
サインアップを外部ログインで行った場合、
-パスワードを持たないアカウントになる。
-この場合、後からパスワードを設定することで、ローカル・ログオンが可能になる。
--管理画面でパスワード追加する。
--アカウント編集画面でパスワード追加する。
--パスワード・リセットを行なう。

-E-mailアドレスの確認(E-mail confirmation)
--外部ログイン処理で取得したE-mailアドレスは確認しない。
--外部ログイン処理で取得したE-mailアドレスは確認しない。~
(信頼するIdPのSTSで連携されたE-mailアドレスであるため)
--E-mailアドレスでサインアップして、そのままサインインする。

***外部ログインでサインイン [#rcf9978e]
-サインインのみ外部ログインで行った場合、
--既存のアカウントに認証連携でサインインできる。
--認証連携で必要なクレーム(属性値)を連携して上書きできる。
--UserNameやE-mailなど、変更できない属性値もある。
-ローカル・ログインに外部ログインを重ねるパターンと、~
外部ログインに外部ログインを重ねるパターンとがある。

-外部ログイン追加、サインアップ、サインインの成・否は既定の動作のため省略。
-サインインを外部ログインで行った場合、
--既存のアカウントにID連携でサインインできる。
--ID連携で必要なクレーム(属性値)を連携して上書きできる。
--なお、UserNameやE-mailなど、ID連携で変更できない属性値もある。

***外部ログインの一覧と削除 [#hbd8d5db]
-サインアップ済みの状態から外部ログインの追加 → 削除~
外部ログイン削除後のタイミングで、ログアウトしていないのは、~
代替のログイン手段を持っているため問題無いということ。

-サインアップせずに、外部ログインの追加 → 削除~
--ローカル・ログオンを可能にしていない場合、最後の外部ログインを削除できなくなる。
--パスワード追加でローカル・ログオンを有効化すれば外部ログインを削除できる。
--後からパスワードを設定することでローカル・ログオンを有効化すれば外部ログインを削除できる。

***外部ログインの詳細 [#g27b9c4f]
ExternalLoginCallbackの条件分岐


-AccountController
-AccountController~
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Controllers/AccountController.cs#L1015
--(1) 外部ログインの成否
---失敗(異常終了)
---成功、(2) へ。

--(2) 外部ログインの有・無
---既存の外部ログインがある → クレームを更新してサインイン(正常終了)
---既存の外部ログインがない →新規の外部ログインの追加、(3) へ。

--(3) 外部ログインの追加
---当該ユーザが既にサインアップされている。~
→ 外部ログイン、クレームを追加してサインイン(正常終了)
---当該ユーザが未だサインアップされていない。~
→ サインアップ後に外部ログイン、クレームを追加してサインイン(正常終了)

-ManageController
-ManageController~
https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Controllers/ManageController.cs#L1295
--(1) 外部ログインの成否
---失敗(異常終了)
---成功、(2) へ。

--(2) 外部ログインの有・無
---既存の外部ログインがある → クレーム更新のみ行う(正常終了)
---既存の外部ログインがない →新規の外部ログインの追加、(3) へ。

--(3) 外部ログインの追加
---当該ユーザが既にサインアップされている。~
→ 外部ログイン、クレームを追加してサインイン(正常終了)
---当該ユーザが未だサインアップされていない。~
→ このケースはありえない。

-クレームの連携(追加・更新)時に、ユーザ属性を更新するかどうか?
--案件毎に決定してカスタマイズする。
--既定では、ユーザ属性の更新はしていない。

*[[OAuth>https://techinfoofmicrosofttech.osscons.jp/index.php?OAuth]] 2.0 Server仕様 [#td27d2c1]
*管理機能 [#ga313890]
**管理者アカウント [#ba05d72a]
システム管理者アカウントサインインして管理操作を実行できる。

**概要 [#k234ea79]
概ね、[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]に準拠。
**ユーザ・ロール編集処理 [#ue4c3ec1]
-管理画面についての詳細は[[こちら>汎用認証サイトのファーストステップガイド (2)#f0c1d26f]]。

-[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]側の仕様
-[[OAuth>https://techinfoofmicrosofttech.osscons.jp/index.php?OAuth]]を拡張した認証の仕様
-システム管理者アカウントのみ操作可能。~
(マルチテナント機能は v01-10 で削除した。)

については、「[[ASP.NET IdentityによるSTS実装>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity%E3%81%AB%E3%82%88%E3%82%8BSTS%E5%AE%9F%E8%A3%85]]」を参照。
*エラーメッセージ [#r932c23a]

**共通 [#c15cd000]
**表示元 [#ee798d72]

***Server側 [#odd02418]
-AuthorizationServer
--認可エンドポイント
---redirect_uriチェックは不要(部分一致をサポートしない完全事前登録制とするため)
--Tokenエンドポイント(Access Tokenの発行方法)
---scope=その他の値の場合、scopeパラメタ値をClaimに格納する(通常の動作)。
***ASP.NET MVCのModel Bindingの検証機能によるもの。 [#m16451b3]
-[[ASP.NET MVCのModel Bindingの検証機能>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20MVC%E3%81%AE%E5%88%A9%E7%94%A8%E6%96%B9%E6%B3%95#za7f960c]]による単項目チェックを使用。~
(Compare属性など、一部、関連チェック相当の検証機能もある)。

-ResourceServer
--リソース・アクセス用のWeb APIを提供する。
-検証項目と内容については、各画面で使用している[[ViewModel>https://github.com/OpenTouryoProject/MultiPurposeAuthSite/tree/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Models/ViewModels]]を参照のこと。

***Client側 [#y0f2a018]
-パラメタ
--redirect_uri指定は不要(部分一致をサポートしない完全事前登録制とするため)
--state指定は必須(ID Tokenのnonce Claimにコレを設定する)。
-エラーメッセージ~
例 : https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Models/ViewModels/AccountRegisterViewModel.cs

-ResourceServerリソース・アクセス用のWeb APIにアクセスする場合、
--Access TokenをHTTPヘッダに指定して送信する。
--既定値~
以下のような属性では、既定のエラーメッセージを使用。
---[EmailAddress]
---[Required(AllowEmptyStrings = false or truw)]

***Access Token [#d98eac8c]
-Access Tokenのフォーマットには[[JWT>https://techinfoofmicrosofttech.osscons.jp/index.php?JWT]]アサーションを使用する。
--この[[JWT>https://techinfoofmicrosofttech.osscons.jp/index.php?JWT]]アサーションには、OpenID Connectと同様のID Tokenを含める。
--Access TokenはOAuthAuthorizationServerOptions.AccessTokenFormatに設定した、モジュールで生成される。
--カスタムのエラーメッセージ~
以下のような属性では、カスタム([[Resourcesファイル>https://github.com/OpenTouryoProject/MultiPurposeAuthSite/tree/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Resources]]である*View.resxに定義されている)のエラーメッセージを使用。
 [StringLength(
 ASPNETIdentityConst.MaxLengthOfPassword,
 ErrorMessageResourceName = "MaxLengthErrMsg",
 ErrorMessageResourceType = typeof(Resources.CommonViewModels))]

-AccessTokenFormatモジュールとの情報の受け渡しには、
--[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]の仕組みに準拠し、ClaimsIdentityを使用する。
--ClaimsIdentityには、以下のようなURN形式の文字列をkeyに使用して、~
OAuthAuthorizationServer側からvalueの追加を行う(以下はscopeの値を設定する例)。
 claimsIdentity.AddClaim(new Claim("urn:oauth:scope", xxxxx));
***ASP.NET Identityによるもの。 [#sbc65d2d]
-ASP.NET Identityが返すエラーメッセージ(IdentityResult.Errors)をそのまま利用する。~
例 : https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Controllers/AccountController.cs#L379
--既にサインアップしている場合
--パスワード要件に合わない場合

**クライアント認証 [#g7ed260c]
ここでのクライアントとは、ユーザではなく、[[OAuth>https://techinfoofmicrosofttech.osscons.jp/index.php?OAuth]] 2.0 のClientを指しているので注意する。
***サーバー・サイド実装によるもの。 [#u70f84f3]
-アプリケーションのエラーメッセージを表示する。~
例 : https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Controllers/AccountController.cs#L220
--ModelState.AddModelErrorで検索する。
--エラーメッセージは、[[Resourcesファイル>https://github.com/OpenTouryoProject/MultiPurposeAuthSite/tree/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Resources]]である*Controller.resxに定義されている。

-認可エンドポイントでは、クライアント認証ではなく、Redirectエンドポイントの検証を行う。
-クライアント認証は、Tokenエンドポイントにアクセスする際に行なう。
-ベーシック認証の認証ヘッダを使用して[[クライアント識別子>#hd5f827d]]を送信する。
**表示先 [#r0e2defe]

***クライアント識別子 [#hd5f827d]
-GUIDを使用する
--32文字の英数字。
--URLに指定するので、[{}, -] は無し。
***[[ASP.NET MVCのModel Bindingの検証機能によるもの。>#m16451b3]] [#z3d7d0e1]
-表示位置
--サマリ領域に表示する場合(既定の実装)、
---Html.ValidationSummaryを使用すれば、~
例 : https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Views/Account/Register.cshtml#L45
 @Html.ValidationSummary("", new { @class = "text-danger" })

-client_id~
全てのグラント種別以外で必須
-client_secret
--Implicitグラント種別以外で必須
--ただし、[[ユーザ認証>#k61b5f5a]]で使用する場合は、Implicitグラント種別でも必須。
---div-ul-liタグが用意され、ソコにエラーメッセージが表示される。
 <div class="validation-summary-valid text-danger" data-valmsg-summary="true"><ul><li style="display:none"></li></ul></div>

**ユーザ認証 [#k61b5f5a]
--入力項目の横に表示する場合、
---Html.ValidationMessageForを使用すれば、
 @Html.PasswordFor(m => m.Password, new { @class = "form-control" })
 @Html.ValidationMessageFor(m => m.Password, new { @class = "text-danger" })

***Server側 [#jdc096e3]
-Access TokenにOpenID Connectと同様のID Token([[JWT>https://techinfoofmicrosofttech.osscons.jp/index.php?JWT]]アサーション)を含める。
---入力項目の横にspanが用意され、ソコにエラーメッセージが表示される。
 <input class="form-control" data-val="true" data-val-length="パスワード の長さは 100 文字以下である必要があります。" data-val-length-max="100" data-val-required="パスワード フィールドが必要です。" id="Password" name="Password" type="password" />
 <span class="field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></span>

-ApplicationOAuthBearerTokenProviderの実装
--ValidateClientRedirectUriのオーバーライド
---
--xxxxx
---xxxxxxxxxx
-表示例
--サマリ領域に表示する場合、
#ref(ErrMsg1.png,left,nowrap,サマリ領域に表示したエラーメッセージ)
--入力項目の横に表示する場合、
#ref(ErrMsg2.png,left,nowrap,入力項目の横に表示したエラーメッセージ)

-[[クライアント識別子>#hd5f827d]]は全てのグラント種別で必須となる。
***[[ASP.NET Identityによるもの。>#sbc65d2d]] [#yc9c7b31]
サーバー・サイドのチェック結果が、サマリ領域(Html.ValidationSummary)に表示される。~
例 : https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Views/Account/Register.cshtml#L45
 @Html.ValidationSummary("", new { @class = "text-danger" })

***Client側 [#hc71d0be]
-グラント種別
--できるだけ、Authorization Codeグラント種別を使用する。
--Implicitグラント種別もサポートするが、その場合、~
[[ユーザ認証>#k61b5f5a]]用Access Tokenと[[クライアント識別子>#hd5f827d]]の露見のリスクがあることに注意すること。
--従って、できるだけ、[[JWT>https://techinfoofmicrosofttech.osscons.jp/index.php?JWT]]アサーションをClient側で検証することが推奨される。
***[[サーバー・サイド実装によるもの。>#u70f84f3]] [#ef3d946e]
サーバー・サイドのチェック結果が、サマリ領域(Html.ValidationSummary)に表示される。~
例 : https://github.com/OpenTouryoProject/MultiPurposeAuthSite/blob/develop/root/programs/MultiPurposeAuthSite/MultiPurposeAuthSite/Views/Account/Register.cshtml#L45
 @Html.ValidationSummary("", new { @class = "text-danger" })

-パラメタ
--response_typeには、"code"(推奨) or "token"を指定する。
*[[パラメタ化>汎用認証サイトのコンフィギュレーション]] [#fe16f728]
-[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]や、
-[[汎用認証サイト>汎用認証サイト(Multi-purpose Authentication Site)]]のアプリケーションで

-ResourceServerの[[ユーザ認証>#k61b5f5a]]専用のWebAPIにアクセスする場合、
--[[ユーザ認証>#k61b5f5a]]用Access Tokenに加え、前述の[[クライアント識別子>#hd5f827d]]をPOSTで送信する。
使用するパラメタについて、[[コチラ>汎用認証サイトのコンフィギュレーション]]に纏めた。

***ResourceServerのWebAPI [#f23f0dde]
-/api/OAuthResourceApi/GetUserClaim
*STS仕様 [#g158996e]
-プロトコルに関しては、標準に準拠。
-ただし、実装レベルについては、個別検討が必要([[下記>#lfead2af]]参照)。

*パラメタ化 [#fe16f728]
**Idp [#c4df20df]
[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]や、その他、アプリケーションで使用するパラメタについて。
*参考 [#c596943c]

***SecurityStamp [#u19d11f5]
 <!-- SecurityStamp(検証間隔は10秒、本番は長めに設定-->
 <add key="SecurityStampValidateIntervalFromSeconds" value="10" />
**比較 [#lfead2af]
-Authlete の OAuth 2.0 / OIDC 実装ナレッジ 完全に理解した - r-weblife~
https://ritou.hatenablog.com/entry/2018/10/02/013902

***ユーザ名と、その検証 [#vf58cd02]
-ユーザ名は、E-mailアドレスとする。
-サインアップ後にE-mailアドレスの確認(E-mail confirmation)をする。
**[[GDPR対策]] [#ac810d7d]

 <!--ユーザ名検証(ユーザ名は、E-mail-->
 <add key="AllowOnlyAlphanumericUserNames" value="false" />
 <add key="RequireUniqueEmail" value="true" />

***パスワード検証 [#x111a0c2]
 <!--パスワード検証(8文字以上の大文字・小文字、数値、記号-->
 <add key="RequiredLength" value="8" />
 <add key="RequireNonLetterOrDigit" value="true" />
 <add key="RequireDigit" value="true" />
 <add key="RequireLowercase" value="true" />
 <add key="RequireUppercase" value="true" />

***ユーザ ロックアウト [#d59dc445]
 <!--ユーザ ロックアウト(5 回入力ミスすると、5分ロックアウト-->
 <add key="UserLockoutEnabledByDefault" value="true" />
 <add key="DefaultAccountLockoutTimeSpanFromSeconds" value="300" />
 <add key="MaxFailedAccessAttemptsBeforeLockout" value="5" />

***二要素認証 [#o4aac430]
 <!-- 二要素認証(2FA:TwoFactorAuthentication)-->
 <!-- 必要に応じてユーザが有効にするので初期値は false -->
 <add key="TwoFactorEnabled" value="false" /> 
 <!-- Cookieの有効期限は二週間 24 * 14 = 336 時間 -->
 <add key="TwoFactorCookieExpiresFromHours" value="336" />

**外部ログイン [#ud14e362]
以下のように各、外部ログイン・プロバイダの

-有効化・無効化
-クライアント認証のための[[クライアント識別子>#hd5f827d]]

を設定できる。

 <!-- 外部ログインの追加時に XSRF の防止 -->
 <add key="XsrfKey" value="(サイト毎にで変更する、公開しないこと)" />
  
 <!--外部ログイン(MicrosoftAccountAuthentication)-->
 <add key="MicrosoftAccountAuthentication" value="true" />
 <add key="MicrosoftAccountAuthenticationClientId" value="・・・" />
 <add key="MicrosoftAccountAuthenticationClientSecret" value="・・・" />
  
 <!--外部ログイン(GoogleAuthentication)-->
 <add key="GoogleAuthentication" value="true" />
 <add key="GoogleAuthenticationClientId" value="・・・" />
 <add key="GoogleAuthenticationClientSecret" value="・・・" />
  
 <!--外部ログイン(FacebookAuthentication)-->
 <add key="FacebookAuthentication" value="true" />
 <add key="FacebookAuthenticationClientId" value="・・・" />
 <add key="FacebookAuthenticationClientSecret" value="・・・" />

***設定値の取得方法など [#te545c64]
[[クライアント識別子>#hd5f827d]]は、外部ログイン・サービスの管理画面から取得する。

合わせてここでRedirectエンドポイントの設定などを行う必要がある。~
これは、外部ログイン・サービス毎に設定方法が異なるので注意する。

例えばマイクロソフト・アカウントでは、以下の様な設定を行う。、
 https://fqdnname:nnnnn/signin-microsoft

外部ログイン・サービスによっては、httpやlocalhostをサポートしないことがある。

***XsrfKey [#va1455fb]
-asp.net mvc 5 - What is the XsrfKey used for and should I set the XsrfId to something else? - Stack Overflow~
http://stackoverflow.com/questions/32121504/what-is-the-xsrfkey-used-for-and-should-i-set-the-xsrfid-to-something-else

XsrfKeyは、XSRF = CSRFを防ぐためのstateパラメタの生成に使用される。~
stateパラメタは暗号化によって生成されるので、XsrfKey自体が露見することはない。~
従って、この値としても、無作為な値を使用する必要はない。

**OAuth 2.0 Server [#kf7a470c]

***共通設定 [#ie197aca]
-[[OAuth>https://techinfoofmicrosofttech.osscons.jp/index.php?OAuth]] 2.0 STSの有効化・無効化設定
  <!-- 共通設定 -->
  <add key="EquipOAuthServer" value="true" />

-OAuthAuthorizationServerOptions
  <!-- プロパティ -->
  <add key="AllowOAuthInsecureHttpEndpoints" value="true" />
  <add key="OAuthAuthorizeEndpointCanDisplayErrors" value="true" />
  <add key="OAuthAccessTokenExpireTimeSpanFromMinutes" value="360" />
  <add key="OAuthRefreshTokenExpireTimeSpanFromDays" value="14" />

-[[JWT>https://techinfoofmicrosofttech.osscons.jp/index.php?JWT]]アサーション関連の設定
  <!-- JWT -->
  <add key="OAuthIssuerId" value="http://jwtssoauth.opentouryo.com" />
  <!-- JWTの署名に使用する X.509 証明書に関するパラメタ -->
  <add key="OAuthJWTPassword" value="xxxxx" />
  <add key="OAuthJWT_pfx" value="XXXXX_RS256.pfx" />
  <add key="OAuthJWT_cer" value="XXXXX_RS256.cer" />

-Grant Typeの有効・無効
  <!-- Grant Typeの有効・無効 -->
  <add key="EnableResourceOwnerCredentialsGrantType" value="true" />
  <add key="EnableClientCredentialsGrantType" value="true" />
  <add key="EnableRefreshToken" value="true" />

***Server側エンドポイント [#e48bbad2]
-Authorization Serverエンドポイント
  <!-- AuthorizationServerエンドポイント --> 
  <add key="OAuthAuthorizationServerEndpointsRootURI" value="http://localhost:nnnnn/MultiPurposeAuthSite" />
  <!-- 認可エンドポイント -->
  <add key="OAuthAuthorizeEndpoint" value="/Account/OAuthAuthorize" />
  <!-- Tokenエンドポイント -->
  <add key="OAuthBearerTokenEndpoint" value="/OAuthBearerToken" />

-Resource Serverエンドポイント
  <!-- ResourceServerエンドポイント -->
  <add key="OAuthResourceServerEndpointsRootURI" value="http://localhost:nnnnn/MultiPurposeAuthSite" />
  <add key="OAuthAuthenticateUserWebAPI" value="/api/OAuthResourceApi/AuthenticateUser" />
  <add key="OAuthGetUserClaimWebAPI" value="/api/OAuthResourceApi/GetUserClaim" />

***Client側エンドポイント [#c862d00c]
  <!-- Client -->
  <!-- Clientエンドポイント -->
  <add key="OAuthClientEndpointsRootURI" value="http://localhost:nnnnn/MultiPurposeAuthSite" />
  <!-- Redirectエンドポイント -->
  <!--  - test_self_code : Authorization Codeグラント種別 -->
  <add key="OAuthAuthorizationCodeGrantClient" value="/Account/OAuthAuthorizationCodeGrantClient" />
  <!--  - test_self_token : Implicitグラント種別 -->
  <add key="OAuthImplicitGrantClient" value="/Account/OAuthImplicitGrantClient" />

***[[クライアント識別子>#hd5f827d]] [#mc385a2d]
以下をツールを使用して生成して、登録する。

-先頭の[[クライアント識別子>#hd5f827d]]は、テスト用Redirectエンドポイントを使用するテスト用。
-以降の[[クライアント識別子>#hd5f827d]]は、ユーザのサイト。

  <!-- クライアント識別子 (client_id, client_secret, redirect_uri) -->
  <add key="OAuthClientsInformation" value='
       {
         "-guid(client_id)-": {
           "client_secret": "-乱数-",
           "redirect_uri_code": "test_self_code",
           "redirect_uri_token": "test_self_token",
           "client_name": "TestUser"
         },
         "-guid(client_id)-": {
           "client_secret": "-乱数-",
           "redirect_uri_code": "http://hogehoge0/aaa",
           "redirect_uri_token": "http://hogehoge0/bbb",
           "client_name": "hogehoge0"
         },
         "-guid(client_id)-": {
           "client_secret": "-乱数-",
           "redirect_uri_code": "http://hogehoge1/aaa",
           "redirect_uri_token": "http://hogehoge1/bbb",
           "client_name": "hogehoge1"
         },
         "-guid(client_id)-": {
           "client_secret": "-乱数-",
           "redirect_uri_code": "http://hogehoge2/aaa",
           "redirect_uri_token": "http://hogehoge2/bbb",
           "client_name": "hogehoge2"


トップ   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS