[[Open棟梁Project>http://opentouryo.osscons.jp/]] - [[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]] -[[戻る>OAuth]] * 目次 [#ba45eec0] #contents *概要 [#nf08aeca] 前提知識に、[[OAuth]] 2.0 の知識を要する。 >そもそも、[[OAuth]] 2.0 を認証に使用すると、~ 「セキュリティ的に問題に成り得る。」と言う[[懸念点>OAuth#add861ca]]が幾つか在った。 OAuthによる外部ログイン(認証)をすると、通常、 [[OAuth]] 2.0 の Authorization Server で認証されたユーザのクレームが~ Redirectエンドポイントに返るが、これは、[[OAuth]] 2.0 自体の仕様ではない。 *外部ログイン(認証)の拡張仕様 [#m5ae941c] これは、[[OAuth]] 2.0「Authorization Codeグラント種別」の拡張仕様になる。 -通常、[[OAuth]] 2.0では、Redirectエンドポイントには、仲介コードが返り、~ 仲介コードをサーバ側でAccess Tokenに変換した後、Resources Serverへアクセスし、~ 必要なResources(ここでは認証されたユーザのクレーム)を取り出して返すと言う流れになる。~ -しかし、外部ログインでは、Redirectエンドポイントに直接、このクレームが返る~ (外部ログイン・ライブラリ上で、仲介コード → Access Token → クレームへの変換処理をしている)。 **ASP.NET Identity用のMicrosoftアカウントの外部ログイン・ライブラリの場合 [#jf7626f6] 動作を分析した所、 -実際のRedirectエンドポイントは、~ http://localhost:nnnnn/signin-microsoft -アプリケーションのCallbackのエンドポイントが、~ /Account/ExternalLoginCallback となっている。 HTTPSのため、仲介コード → Access Tokenの、Responseを確認できず、~ [[OpenID Connect]]で実装されてる可能性もあると考えたが、~ scopeパラメタに「openid」の値を確認できなかったので、[[OAuth]] 2.0拡張と思われる。 ***Redirectエンドポイント [#yd211b3f] 仲介コード → Access Token → クレームへの変換処理を行っている模様。 -GET http://localhost:nnnnn/signin-microsoft?code=AAAAA&state=BBBBB HTTP/1.1 -Cookie: --ASP.NET_SessionId=XXXXX --__RequestVerificationToken=YYYYY --.AspNet.Correlation.Microsoft=ZZZZZ1 ***Callbackのエンドポイント [#mc069e8d] この時点で情報は全て、.AspNet.ExternalCookieに同梱されるもよう。~ (恐らく、クレームなどの情報の露見を防ぐためと思われる) -GET http://localhost:nnnnn/Account/ExternalLoginCallback HTTP/1.1 -Cookie: --ASP.NET_SessionId=XXXXX --__RequestVerificationToken=YYYYY --.AspNet.ExternalCookie=ZZZZZ2 ***遷移元への遷移 [#z6e7095a] 認証後、遷移元へ遷移した後には、外部ログインの形跡は綺麗に消えている。 -GET http://localhost:nnnnn/ HTTP/1.1 -Cookie: --ASP.NET_SessionId=XXXXX --__RequestVerificationToken=YYYYY --.AspNet.TwoFactorRememberBrowser=ZZZZZ3 --.AspNet.ApplicationCookie=ZZZZZ4 ***セキュリティに関する考慮点 [#j218c1c3] 以下をライブラリ内で処理することで、セキュリティを高くしている。 -外部ログインを、ライブラリ内部で処理して、 --ユーザの実装ミスによる仲介コード、Access Token等の露見を防いでいる。 --長目のRequestVerificationToken値を使用している。 -Redirectエンドポイント→Callbackのエンドポイント間で、 --仲介コード、Access Token等が露見しないよう、エンドポイントを2段構成にしている。 --エンドポイント間のインターフェイスにCookie(ExternalCookie)を使用し、遷移後、直ちに削除している。 **OAuth 2.0 Multiple Response Type Encoding Practices [#oae281fb] code token(Hybrid Flow)などの、新しいresponse_typeが追加されている。 -Final: OAuth 2.0 Multiple Response Type Encoding Practices~ http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html ***参考 [#p880c26e] -GoogleのOAuth 2.0実装におけるToken置換攻撃の防ぎ方 - r-weblife~ http://d.hatena.ne.jp/ritou/20120702/1341235859 -OAuth 2.0 の Response Type 全パターン - OAuth.jp~ http://oauth.jp/blog/2015/01/06/oauth2-multiple-response-type/ **Bearer Tokenやクレームを[[JWT]]フォーマットに変更する [#yf9cec19] Tokenやクレームに、[[JWT]]フォーマットを使用すれば、改竄、置換、CSRF(XSRF)などを検出することができる。 -[[OAuth]] 2.0ではアクセストークンまで仕様化されていないので[[JWT]]を利用可能。~ -認証用途に利用するアクセストークンに、[[OpenID Connect]]の[[IDトークン>OpenID Connect#ofb73c59]]を参考にして、~ 改竄、置換、CSRF(XSRF)等に耐える為のクレームを追加し、これを検証すれば、Implicitグラント種別でも安全性が高くなる。 -また、Google の [[OAuth]] Token は、公開鍵暗号(非対称鍵暗号)で署名された[[JWT]]であるため、~ クライアントは公開鍵を取得し、Google API にサーバー・サイド検証のリクエストをせず、クライアント・サイドで検証が可能であるもよう。 ***[[ASP.NET Identity]]でアクセストークンを[[JWT]]フォーマット変更する。 [#fc4ae75b] [[ASP.NET Identity]]でアクセストークンを[[JWT]]フォーマットに変更できるもよう。 詳しくは、[[コチラ>ASP.NET IdentityのOAuthによるSTS実装#a0f5b8a7]]を参照。 ***OAuth2.0 Proof of Possessionというドラフト [#u8ebfddc] 最近、OAuth2.0 Proof of Possessionというドラフトが出て来たらしい。 -draft-ietf-oauth-pop-architecture-08~ OAuth 2.0 Proof-of-Possession (PoP) Security Architecture~ https://tools.ietf.org/html/draft-ietf-oauth-pop-architecture-08 こちらも、アクセストークンを[[JWT]]フォーマットで発行する系らしい。 -参考 --OAuth2.0 Proof of Possession についてまとめてみた - hiyosi's blog~ https://hiyosi.tumblr.com/post/121441878998/oauth20-proof-of-possession-%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%81%BE%E3%81%A8%E3%82%81%E3%81%A6%E3%81%BF%E3%81%9F --RFC7636として発行されたOAuth PKCEとは - r-weblife~ http://d.hatena.ne.jp/ritou/20151018/1445181974 *User-Agentやスマホネイティブでの外部ログインについての考察 [#y96989f1] **課題 [#y4777e16] 問題は、クライアント(User-Agentやスマホネイティブ)という~ 仲介者が存在する中で、サーバ間認証をする必要があること。 ***課題1 [#n3075467] User-Agentやスマホネイティブで上記外部ログイン方式に習い、~ [[OAuth]] 2.0の「Implicitグラント種別」でClientではなく、~ "仲介者"であるUser-Agentやスマホネイティブに返したクレームを使って~ サーバ認証というのも意味不明な(認証になって無い)仕様なので、~ 結局、User-Agentやスマホネイティブでも -「Authorization Codeグラント種別」で -サーバ(AuthorizationServerとClient)間で 外部ログインするしか無いのか? ***課題2 [#hd0bbd17] 外部ログインした場合、その後に、 サーバとクライアント(User-Agentやスマホネイティブ)間で認証するための認証チケット(的なモノ)を、~ サーバが、(改竄、置換などの攻撃を行う可能性のある)"仲介者"であるクライアントへ発行する必要がある。 **解決 [#z2e54cac] [[JWT]]を使用すれば、クライアントを経由しても、~ 安全にサーバ間で認証可能な、認証チケット(的なモノの)を発行できる。 ***方法 [#zdd6e43b] [[コチラ>JWT#yd304024]]を参照。 *参考 [#cd0c604f] -[[OAuth]] -[[ASP.NET Identityの外部ログイン]] -[[ASP.NET IdentityによるSTS実装]] --[[ASP.NET IdentityのOAuthによるSTS実装]] ---- Tags: [[:認証基盤]], [[:ASP.NET Identity]], [[:OAuth]]