[[Open棟梁>https://github.com/OpenTouryoProject]] wiki -[[戻る>Multi-AuthSystem]] *目次 [#w492a716] #contents *概要 [#p3c82f83] Multi-AuthSystem独自仕様部分について説明する。 *Idp仕様 [#c803a92a] Idpの使用について。 **概要 [#lab61c15] 概ね、ASP.NET Identityに準拠。 ASP.NET Identity側の仕様については、「[[ASP.NET Identity>https://techinfoofmicrosofttech.osscons.jp/index.php?ASP.NET%20Identity]]」を参照。 **カスタマイズポイント [#z2504cd5] ***ユーザアカウント [#p70b0543] -UserId = e-mail address = UserNameとする。 -Passwordの強度は[[下記の設定>#pe833de6]]に従う。 ***UserStore [#gd06e168] -EntityFrameworkをキャンセルしUserStoreクラスで実装。 -DBMSはSQL Server or PostgreSQLを使用。 -Open棟梁のB・D層を使用してデータアクセスを実装。 **パラメタ化 [#pe833de6] ASP.NET Identityや、その他、アプリケーションで使用するパラメタについて。 ***SecurityStamp [#h652b8fd] <!-- SecurityStamp(検証間隔は10秒、本番は長めに設定--> <add key="SecurityStampValidateIntervalFromSeconds" value="10" /> ***ユーザ名と、その検証 [#x5d3a6ba] <!--ユーザ名検証(ユーザ名は、E-mail--> <add key="AllowOnlyAlphanumericUserNames" value="false" /> <add key="RequireUniqueEmail" value="true" /> ***パスワード検証 [#mb726395] <!--パスワード検証(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" /> ***ユーザ ロックアウト [#se80b47a] <!--ユーザ ロックアウト(5 回入力ミスすると、5分ロックアウト--> <add key="UserLockoutEnabledByDefault" value="true" /> <add key="DefaultAccountLockoutTimeSpanFromSeconds" value="300" /> <add key="MaxFailedAccessAttemptsBeforeLockout" value="5" /> ***二要素認証 [#r58fd201] <!-- 二要素認証(2FA:TwoFactorAuthentication)--> <!-- 必要に応じてユーザが有効にするので初期値は false --> <add key="TwoFactorEnabled" value="false" /> <!-- Cookieの有効期限は二週間 24 * 14 = 336 時間 --> <add key="TwoFactorCookieExpiresFromHours" value="336" /> *外部認証仕様(≒ OAuth 2.0 Client仕様) [#q865b16d] 「≒」としたのは、外部認証の主要プロトコルがOAuth 2.0であって、~ 今後、[[OpenID Connect>https://techinfoofmicrosofttech.osscons.jp/index.php?OpenID%20Connect]]などの他のプロトコルに置き換えられていく可能性があるため。 **概要 [#ac980dda] 概ね、ASP.NET Identityに準拠。 ASP.NET Identity側の仕様については、「[[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]]」を参照。 **カスタマイズ・ポイント [#u7a996a6] 外部認証処理の仕様について。 -外部認証処理で取得したe-mail addressは検証しない。 -e-mail addressでサインアップして、そのままサインインする。 -初回のサインアップを外部認証で行った場合、パスワードを持たないアカウントになる。~ この場合、後からパスワードを持ったアカウントとしての登録が不可能になる(★パスワードリセット不可能?)。 **パラメタ化 [#r210fb5c] 以下のように各、外部ログイン・プロバイダの([[OAuth>https://techinfoofmicrosofttech.osscons.jp/index.php?OAuth]]等)の -有効化・無効化 -クライアント認証のためのクライアント識別子 を設定できる。 <!-- 外部ログインの追加時に 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="・・・" /> ***設定値の取得方法など [#fe43fb5c] クライアント識別子は、外部ログイン・サービスの管理画面から取得する。 合わせてここでRedirectエンドポイントの設定などを行う必要がある。~ これは、外部ログイン・サービス毎に設定方法が異なるので注意する。 例えばマイクロソフト・アカウントでは、以下の様な設定を行う。、 https://fqdnname:nnnnn/signin-microsoft 外部ログイン・サービスによっては、~ httpやlocalhostをサポートしないことがある。 マイクロソフト・アカウントでは、部分一致をサポートしており、~ Redirectエンドポイントの以降のパスはredirect_uriから指定する。 外部ログインは、[[HttpUnauthorizedResult>https://msdn.microsoft.com/ja-jp/library/system.web.mvc.httpstatuscoderesult.aspx]]のActionResultを返すことで開始する。~ redirect_uriはHttpUnauthorizedResultのコンストラクタから指定できる。 ***XsrfKey [#v08882f3] -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仕様 [#q3ec8431] **概要 [#s811486b] 概ね、ASP.NET Identityに準拠。 ASP.NET Identity側の仕様については、「[[ASP.NET IdentityによるSTS実装>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側の仕様については、「[[ASP.NET Identity追加仕様>]]」を参照。 **共通 [#se391923] ***Server側 [#k813af7a] -AuthorizationServer --認可エンドポイント ---redirect_uriチェックは不要(部分一致をサポートしない完全事前登録制とするため) --Tokenエンドポイント(Access Tokenの発行方法) ---scope=その他の値の場合、scopeパラメタ値をClaimに格納する(通常の動作)。 -ResourceServer --リソース・アクセス用のWebAPIを提供する。 ---"urn:oauth:scope"のClaimがあった場合、scopeの値に適合した範囲のアクセス権で処理を行う。 ***Client側 [#jdcc345f] -パラメタ --redirect_uri指定は不要(部分一致をサポートしない完全事前登録制とするため) --stateの使用を強く推奨する(Access Token露見は、Client側の自己責任のため)。 -ResourceServerリソース・アクセス用のWebAPIにアクセスする場合、 --Access TokenをHTTPヘッダに指定して送信する。 ***Access Tokenへの情報格納方法 [#l465fe76] ClaimsIdentityを使用する。以下のようなURN形式をkeyに使用してvalueの追加を行う。 -"scope=auth"の場合(Access Tokenが[[ユーザ認証>#tf864e14]]用であることを意味する。詳しくは[[下記>#oa657de9]]参照) claimsIdentity.AddClaim(new Claim("urn:oauth:auth", client_id)); -"scope=その他の値"の場合、 claimsIdentity.AddClaim(new Claim("urn:oauth:scope", scope)); **クライアント認証 [#u994461a] ここでのクライアントとは、[[OAuth>https://techinfoofmicrosofttech.osscons.jp/index.php?OAuth]] 2.0 のClientを指しているので注意する。 -認可エンドポイントでは、クライアント認証ではなく、Redirectエンドポイントの検証を行う。 -クライアント認証は、Tokenエンドポイントにアクセスする際に行なう。 -ベーシック認証の認証ヘッダを使用して[[クライアント識別子>#bd77b31a]]を送信する。 ***[[クライアント識別子>#bd77b31a]] [#hb59710b] -GUIDを使用する --32文字の英数字。 --URLに指定するので、[{}, -] は無し。 -client_id~ 全てのグラント種別以外で必須 -client_secret --Implicitグラント種別以外で必須 --ただし、[[ユーザ認証>#tf864e14]]で使用する場合は、Implicitグラント種別でも必須。 **ユーザ認証 [#tf864e14] -ユーザ認証に利用する場合、以下の仕様に準拠する。 -[[クライアント識別子>#bd77b31a]]は全てのグラント種別で必須 ***Server側 [#oa657de9] -AuthorizationServer --Tokenエンドポイント(Access Tokenの発行方法) ---scope=authの場合、client_idをClaimに格納し、Access Tokenがユーザ認証用であることを明示する。 -ResourceServer --ユーザ認証専用のWebAPIを提供する。 ---"urn:oauth:auth"のClaimがあった場合、Access Tokenがユーザ認証用であることを意味する。 ---この場合、POSTされた[[クライアント識別子>#bd77b31a]]でクライアント認証をした後、~ そのClaim値とclient_idを比較してTokenに問題がないかをチェックする。 ***Client側 [#x001826d] -グラント種別 --できるだけ、Authorization Codeグラント種別を使用する。 --Implicitグラント種別もサポートするが、その場合、~ ユーザ認証用Access Tokenと[[クライアント識別子>#bd77b31a]]の露見のリスクがあることに注意すること。 -パラメタ --response_typeには、"code"(推奨) or "token"を指定する。 --ユーザ認証を行なう場合、scopeパラメタに"auth"を指定する。 -ResourceServerのユーザ認証専用のWebAPIにアクセスする場合、 --ユーザ認証用Access Tokenに加え、前述の[[クライアント識別子>#bd77b31a]]をPOSTで送信する。 ***ResourceServerのWebAPI [#u68a575d] -認証専用のWebAPI --/api/OAuthResourceApi/GetAuthenticatedUsersClaim -リソース・アクセス用のWebAPI --/api/OAuthResourceApi/XXXXX **パラメタ化 [#k2595218] ***共通設定 [#lcf9fd19] <add key="EquipOAuthServer" value="true" /> <add key="OAuthIssuerId" value="IssuerId:サイト毎にGUIDの32文字を生成して設定" /> <add key="AllowOAuthInsecureHttpEndpoints" value="true" /> <add key="OAuthAuthorizeEndpointCanDisplayErrors" value="true" /> <add key="OAuthAccessTokenExpireTimeSpanFromMinutes" value="360" /> ***Server側エンドポイント [#o0322317] Multi-AuthSystemが保有するエンドポイントなで、相対パスで良い。 <!-- 認可エンドポイント --> <add key="OAuthAuthorizeEndpoint" value="/Account/OAuthAuthorize" /> <!-- Tokenエンドポイント --> <add key="OAuthBearerTokenEndpoint" value="/OAuthBearerToken" /> <!-- ResourceServerエンドポイント --> <add key="OAuthAuthenticateAPI" value="/api/OAuthResourceApi/Authenticate" /> <add key="OAuthAuthorizedUserClaimAPI" value="/api/OAuthResourceApi/GetAuthorizedUserClaim" /> ***Client側エンドポイント [#dd6249b1] Clientだが、Multi-AuthSystemが保有する[[セルフRedirectエンドポイント>#bc429bf4]]なので、相対パスで良い。 <!-- Redirectエンドポイント --> <!-- - self_code : Authorization Codeグラント種別 --> <add key="OAuthAuthorizationCodeGrantClient" value="/Account/OAuthAuthorizationCodeGrantClient" /> <!-- - self_token : Implicitグラント種別 --> <add key="OAuthImplicitGrantClient" value="/Account/OAuthImplicitGrantClient" /> ***[[クライアント認証用の識別子登録>#u994461a]] [#nd32db3d] <!-- クライアント識別子 (client_id, client_secret, redirect_uri) --> <add key="OAuthClientsInformation" value=' { "client_idとしてサイト毎にGUIDの32文字を生成して設定": { "client_secret": "サイト毎にGUIDの32文字を生成して設定", "redirect_uri": "self_code" }, "client_idとしてサイト毎にGUIDの32文字を生成して設定": { "client_secret": "サイト毎にGUIDの32文字を生成して設定", "redirect_uri": "self_token" }, "client_idとしてサイト毎にGUIDの32文字を生成して設定": { "client_secret": "サイト毎にGUIDの32文字を生成して設定", "redirect_uri": "self_token_web" }, "client_idとしてサイト毎にGUIDの32文字を生成して設定": { "client_secret": "サイト毎にGUIDの32文字を生成して設定", "redirect_uri": "self_token_mob:アプリ間連携用URI" }, "client_idとしてサイト毎にGUIDの32文字を生成して設定": { "client_secret": "サイト毎にGUIDの32文字を生成して設定", "redirect_uri": "http://hogehoge/・・・" }, ・・・ } ' /> **セルフRedirectエンドポイント [#bc429bf4] テスト用のRedirectエンドポイントだが、~ スマホネイティブの認証などでサイトを構築せず利用可能。 ***self_code [#m9dac4ff] "redirect_uri": "self_code" -Authorization Codeグラント種別を検証するRedirectエンドポイント。 -用途はテスト用(本番用には使用しないこと) --Access TokenやRefresh Tokenを含むHTMLをreturnする。~ (あくまで検証用であり、本番ではTokenをreturnしないこと) --サーバ側でResourceServerにアクセスした結果を含むHTMLをreturnする。 ***self_token, self_token_web [#v210b617] "redirect_uri": "self_token"~ "redirect_uri": "self_token_web" -Implicitグラント種別を検証するRedirectエンドポイント。 -用途はテスト用(本番用には使用しないこと) --Access Tokenを含むHTML+JavaScriptをreturnする。 ***self_token_mob [#lb092cae] "redirect_uri": "self_token_mob" -Implicitグラント種別を検証するRedirectエンドポイント。 -用途はテスト用だけでなく、本番用も想定している。 --Access Tokenを含むHTML+JavaScriptをreturnし、~ 事前登録したアプリ間連携用URIを使用してアプリ間でAccess Tokenを受け渡す。 --ネイティブ・アプリでは、コレを使用して認証・認可が可能。