「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。 -戻る --[[JWTとOAuth2.0 > クライアント認証>JWTとOAuth2.0#bdaa0ed5]] --[[OpenID Connect - Requestオブジェクト]] --[[FAPI Part 2 (Read and Write API Security Profile)]] * 目次 [#l3592235] #contents *概要 [#r41f749f] -このページは、ドラフト 15 を参考にして作成。 -[[F-API2>FAPI Part 2 (Read and Write API Security Profile)#ha94c6d8]]でのユースケースは限定的で分かり易いが、~ こちらのフルスペックは若干意味不明(私が理解できていないダケ)。 **弱点 [#md2aded4] 以下の弱点のために、 -通信の送信元が認証されていない。 -TLS末端は保護されないため、パラメタ汚染、通信監視が可能。 --TLSセッションは、UserAgentで終了する。 --TLSセッションは、ロードバランサなど(ミドルボックス)で時期尚早に終了することがある。 **攻撃 [#s0e182ac] 以下の攻撃が可能。 -Redirect URI書き換え攻撃 -ミックスアタック攻撃[FETT] **対策 [#j0e1699d] 対策として、認可リクエストのパラメタ群を[[JWT]]で送信する~ (認証要求に署名し、オプションで暗号化できる。)~ 本[[OAuth 2.0 拡張]]が[[OpenID Connect]]によって追加された。 **効果 [#d046bbb6] このアプリケーション層セキュリティの使用により、 -許可要求の機密性、完全性が達成され、 -これらの問題が緩和される。 **サード・パーティー [#m5a17a21] 本仕様(コンテキスト)中で、「サード・パーティー」という用語は、以下に関連する。 -[[Assertion Created by Third Party>JWT bearer token authorizationグラント種別#vf7e7da7]] -[[Self-Issued Assertion>JWT bearer token authorizationグラント種別#n8fdd9f7]] *Requestオブジェクト [#l71999b4] **内容 [#vb813dbf] [[JWT]]化された認可リクエストのパラメタ群をRequestオブジェクトと呼ぶ。 ***生成方法 [#ra39c605] -Requestオブジェクト([[JWT]])は、 --[[JWS]]で署名し、 --必要に応じて[[JWE]]で暗号化する。 -署名と暗号化が必要な場合、 --署名の後、暗号化を行う(逆はダメ)。 --詳しくは[[[RFC7519]の11.2節>https://tools.ietf.org/html/rfc7519#section-11.2]]を参照 ***効果 [#t72713f4] -合意した以上のアクセス権を要求できないようにすることで、プライバシーを保護する。 -この場合、認可プロンプトをスキップすることが望ましい場合もある。 -以下のような少数例にも適合する。 --送信される要求のサイズを小さくすることが望ましい場合(秘密鍵?)。 --Clientが暗号を行いたくないとき([[JWS]]で署名し、TLSを使用する)。 ***クレームセット [#od26debf] Requestオブジェクト([[JWT]])のペイロードをbase64urlデコードした文字列。~ 認可Requestの全てのパラメタがRequestオブジェクトに同梱されている。 -ヘッダ(共通) { "alg": "RS256", "kid": "k2bdc" } -ペイロード~ ※ nonceやmax_ageなどの拡張変数が含まれる。 --通常 { "iss": "s6BhdRkqt3", "aud": "https://server.example.com", "response_type": "code id_token", "client_id": "s6BhdRkqt3", "redirect_uri": "https://client.example.org/cb", "scope": "openid", "state": "af0ifjsldkj", "nonce": "n-0S6_WzA2Mj", "max_age": 86400 } --[[claimsリクエスト・パラメタ>OpenID Connect#e26320e4]]を含む。 { "iss": "s6BhdRkqt3", "aud": "https://server.example.com", "response_type": "code id_token", "client_id": "s6BhdRkqt3", "redirect_uri": "https://client.example.org/cb", "scope": "openid", "state": "af0ifjsldkj", "nonce": "n-0S6_WzA2Mj", "max_age": 86400, "claims": { "userinfo": { "given_name": { "essential": true }, "nickname": null, "email": { "essential": true }, "email_verified": { "essential": true }, "picture": null }, "id_token": { "gender": null, "birthdate": { "essential": true }, "acr": { "values": [ "urn:mace:incommon:iap:silver" ] } } } } ***公開鍵 [#lcd844f4] 署名を検証する場合、[[JWK]]形式で表されるRSA公開鍵を使用する。~ ※ [[jwks_uriにJWK Setを公開>#kd650a0c]]する。 { "kty":"RSA", "kid":"k2bdc", "n":"y9Lqv4fCp6Ei-u2-ZCKq83YvbFEk6JMs_pSj76eMkddWRuWX2aBKGHAtKlE5P 7_vn__PCKZWePt3vGkB6ePgzAFu08NmKemwE5bQI0e6kIChtt_6KzT5OaaXDF I6qCLJmk51Cc4VYFaxgqevMncYrzaW_50mZ1yGSFIQzLYP8bijAHGVjdEFgZa ZEN9lsn_GdWLaJpHrB3ROlS50E45wxrlg9xMncVb8qDPuXZarvghLL0HzOuYR adBJVoWZowDNTpKpk2RklZ7QaBO7XDv3uR7s_sf2g-bAjSYxYUGsqkNA9b3xV W53am_UZZ3tZbFTIh557JICWKHlWj5uzeJXaw", "e":"AQAB" } **渡し方 [#cf64a89f] Requestオブジェクトの渡し方にはrequestとrequest_uriの2つのパラメタを使用する方法がある。 -requestとrequest_uriパラメタを、[[OAuth]] 2.0 の追加の認証要求パラメタとして導入。 -パラメタは「application/x-www-form-urlencoded = QueryString」として渡す。 ***requestパラメタ [#ye252787] Requestオブジェクトの値を直接渡す。 -認可エンドポイント https://server.example.com/authorize?request=eyJhbG..AlMGzw ***request_uriパラメタ [#lcb4340f] -認可エンドポイント --Requestオブジェクトの場所をuriで伝える。 --uriは、512 ASCII文字を超えてはならない。 https://server.example.com/authorize? response_type=code%20id_token &client_id=s6BhdRkqt3 &request_uri=https%3A%2F%2Ftfp.example.org%2Frequest.jwt %23GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM &state=af0ifjsldkj ※ この場合、response_type, client_id, state値の同梱が必要。~ (下位互換などのため、)QueryStringに同じパラメタが指定できるダケ。 -request_uriエンドポイント 通常は、ローカルの検索ではなく、HTTPのRequestを行う。 --Request GET /request.jwt HTTP/1.1 Host: tfp.example.org --Response HTTP/1.1 200 OK Date: Thu, 16 Feb 2017 23:52:39 GMT Server: Apache/2.2.22 (tfp.example.org) Content-type: application/jwt Content-Length: 1250 Last-Modified: Wed, 15 Feb 2017 23:52:32 GMT ey・・・(JWT)・・・ --アクセス制御対策 ---第三者に公開しても良い。 ---Authorization Serverだけ公開するパラメタを含む場合、~ 以下のように、存続期間に適切なエントロピーを持たせる。 https://tfp.example.org/request.jwt#GkurKxf5T0Y-mnPFCHqWOMiZi4VS138cQO_V7PZHAdM *実装 [#r8ebe8ae] 下記手順で取得したRequestオブジェクトを署名検証(若しくは復号)する。 **サード・パーティー [#g5378246] この章に書かれている「jwks_uriにJWK Setを公開」する実装例は、 -[[サード・パーティー>#m5a17a21]]に依る「Assertion Created by Third Party」実装の場合か?~ -Clientに依る場合、「Self-Issued Assertion」実装で良い気がする。 **復号化 [#c69daf29] Requestオブジェクトが暗号化されている場合、~ 下記手順で取得したRequestオブジェクトを復号化する。 ***復号化の処理 [#t8fedcf6] -Requestオブジェクトの復号用の鍵を取得。~ クライアント・メタデータの登録・有無によってシーケンスが異なる。 --登録されている場合、~ [[JWK Set>JWK#od5799a4]]をjwks クライアントメタデータ値から取得。 --登録されていない場合、~ jwks_uriからクライアント・メタデータ([[JWK Set>JWK#od5799a4]])を取得。 -Requestオブジェクトを復号化して、 --認可エンドポイントへのパラメタ --若しくは、Requestオブジェクト(署名) >を取り出す。 ***復号化の失敗 [#md2d1ce6] 復号化に失敗した場合、Authorization Serverは「invalid_request_object」エラーを返す。 **署名検証 [#za061c6f] 下記手順で取得したRequestオブジェクトを署名検証する。 ***署名検証の処理 [#kd650a0c] -Requestオブジェクトの署名・検証用の鍵を取得。~ クライアント・メタデータの登録・有無によってシーケンスが異なる。 --登録されている場合、~ [[JWK Set>JWK#od5799a4]]をjwks クライアントメタデータ値から取得。 --登録されていない場合、~ jwks_uriからクライアント・メタデータ([[JWK Set>JWK#od5799a4]])を取得。 -Requestオブジェクトから認可エンドポイントへのパラメタを取り出す。 ***署名検証の失敗 [#p9111c44] 署名検証に失敗した場合、Authorization Serverは「invalid_request_object」エラーを返す。 **パラメタ検証 [#e2412309] Authorization Serverは、 -(下位互換などのため、)QueryStringに同じパラメタが指定することもできる。~ しかし、パラメタ検証には、Requestオブジェクト内のパラメタのみを使用しなければならない。 -次に[[OAuth]] 2.0 [RFC6749]で指定された要求を検証する。 **追加エラー値 [#q1c5bcf2] ***requestパラメタ [#p31ea27f] -request_not_supported~ Authorization Serverは、requestパラメタの使用をサポートしない。 -invalid_request_object~ requestパラメタに無効なRequestオブジェクトが含まれている。 ***request_uriパラメタ [#i5ede864] -request_uri_not_supported~ Authorization Serverは、request_uriパラメタの使用をサポートしない。 -invalid_request_uri~ request_uriパラメタに対する要求が、エラーか、無効なRequestオブジェクトを返す。 *TLS要件 [#lb85df5e] TLSをサポートしなければならない。 -秘密性と完全性の保護を提供し、情報の漏えいや改ざんから保護する。 -man-in-the-middle攻撃を防ぐため、DNS-ID識別子を使用して、サーバ証明書を検証。 **サーバ証明書要件 [#f52c7f41] -サーバ証明書のDNS名にワイルドカード文字「*」を含めることができる -DNS-ID識別子タイプ(つまり、subjectAltName拡張子のdNSName ID)のサポートが必須 --サーバ証明書を発行する認証機関はDNS-ID識別子タイプをサポート --DNS-ID識別子タイプはサーバ証明書に存在しなければならない **その他 [#d5fb5d33] -クライアントはCN-ID識別子を(認証に)使用してはならない。 -SRV-IDとURI-IDは、比較のために使用してはならない。 *セキュリティに関する考慮事項 [#u50edb30] **ソース認証 [#d4ee4439] 認可リクエストの送信元は常に検証されなければならない。 ***Requestオブジェクトの暗号処理 [#g83481aa] -Requestオブジェクトの署名検証を行う。 -Requestオブジェクトの復号用の秘密鍵が正しいか。 ***request_uriとサーバ証明書 [#s44601f5] request_uriのサーバ証明書のIDを帯域外で知っている必要がある~ (ただし、これは、一般的に信頼された方法ではない(ので後述が推奨?))。 ***request_uriとclient_idのバインド [#s5ba22a4] Authorization Serverは、 -受け入れたRequestオブジェクト中の、~ request_uriとclient_idをバインドするクライアント認証が必要。 -このため、POSTされたRequestオブジェクトと引き換えに、~ request_uriを提供するエンドポイントを提供できる。 --([[以下>#jc15fb21]]を参照すると、恐らく、)ココのエンドポイントで何らかのクライアント認証を行う。 --返した、request_uriを使用すると、client_idを含むRequestオブジェクトを取得できる。 -この場合の、request_uriの要件は、 --有効期間は短く、好ましくはワンタイムにする必要がある。 --また、エントロピーは十分に大きくなければならない。 --これらは、保護されるリソースの価値に依存するが、~ 一般的なガイダンスは、以下の通り。 ---有効時間の1分未満。 ---128bit以上の暗号ランダム値を含める。 ※ [[FAPI Part 2>FAPI Part 2 (Read and Write API Security Profile)#k8b3bfec]]に実例がある。 ***Trust Framework Provider [#kdf4b923] 上記エンドポイントがサード・パーティーのTrust Framework Providerによって提供されても良い。 -上記「[[request_uriとclient_idのバインド>#s5ba22a4]]」と同じ要件が適用される。 -Authorization Serverは、ClientがTrust Framework Providerを利用することを帯域外で知っている必要がある。 **エンドポイント間のリンク [#m9dfb1bb] 以下のエンドポイント間のリンクを張る拡張仕様が必要。~ ([FETT]で紹介されたクロスフェーズ攻撃を防止する) +認可エンドポイント( "authorization_endpoint") +Redirect URI( "redirect_uri") +Tokenエンドポイント( "token_endpoint") +保護されたリソース( "protected_resources") **request_uri関連のリスク [#he99e59e] ***DDoS攻撃 [#s2363060] -不正なクライアントが、不正な"request_uri"を指定する。 -この場合、以下の攻撃が可能になる。 --非常に大きなコンテンツを返す。 --非常に遅く応答する。 --再帰的GETを引き起こす。 ***Request URI Rewrite [#ud6aebf9] -request_uriパラメタの値は署名されていないため、~ man-in-the-middle攻撃によって、改ざんされる可能性がある。 -この場合、以下の攻撃が可能になる。 --書き換えられたURIが指し示す別のファイルを作成して、余分なscopeを要求できる。 --「request_uri」の値を犠牲者の値に設定することによって、DoS攻撃を開始する。 (再帰的GETもできそうだが・・・?) ***対策 [#v78978e9] +request_uriパラメタの値が予期しない場所を指していないこと。 +応答のコンテンツタイプが、"application/jwt"であること。 +request_uriの内容を取得するためのタイムアウトを実装すること。 +request_uriに対する再帰的GETを実行しないこと。 *プライバシーに関する考慮事項 [#k1451c33] RFC6973 **コレクションの制限 [#jc15fb21] 個人情報保護法のため、個人情報を含む場合、厳密にscopeを制限するべき。 -Clientは、登録リクエスト行う。 --[[POSTされたRequestオブジェクト>#s5ba22a4]]を、[[Trust Framework Provider>#kdf4b923]]に提出し、request_uriを取得する。 --クライアント認証可能なリクエストを行う。[[F-API2>FAPI Part 2 (Read and Write API Security Profile)#e104c14f]]にモヤっとした記載がある。 -Authorization Serverは、 --request_uriが[[Trust Framework Provider>#kdf4b923]]のモノか検証する。 --HTTP GET要求をrequest_uriに発行する。 --TLS証明書のサーバIDがrequest_uriと一致するか確認する。 --Clientを表す「client_id」を含むRequest Objectを取得する。 -認可画面は、 --クライアントを指示しなければならず、 --その要求が「コレクションの制限の原則に従うために、~ [[Trust Framework Provider>#kdf4b923]]によって審査されたこと。」を示すべき。 **開示の制限 [#s176c7aa] ***リクエストの開示 [#e4b1f99c] -問題 --この仕様は、拡張パラメタを許可し、ここに機密情報が含まれる可能性がある。 --特にRefererとBrowser履歴を介して、Querystringから漏洩する可能性がある。 -対策 --requestパラメタ~ Requestオブジェクトに機密性の高いパラメタが含まれている場合、~ ClientはRequestオブジェクトを[[JWE]]で暗号化すべき。 --request_uriパラメタ ---[[上記の考慮事項>#s5ba22a4]]を加味すべき。 ---Requestオブジェクトを[[JWE]]で暗号化すべき。 ***ユーザ毎のrequest_uriは避けるべき。 [#sdd2a714] -永続的なユーザ単位のrequest_uriが使用されている場合、ユーザを識別することが可能。 -ブラウザの履歴などでコレを観察し、ユーザ活動との関連付けが可能。 -ある意味では、これはデータ開示でもあり、避けるべき。 *参考 [#o4d0aa71] -OpenID Connect Core 1.0 incorporating errata set 1 > 6. Passing Request Parameters as JWTs~ http://openid.net/specs/openid-connect-core-1_0.html#JWTRequests -The OAuth 2.0 Authorization Framework: JWT Secured Authorization Request (JAR)~ https://tools.ietf.org/html/draft-ietf-oauth-jwsreq -OAuth & OpenID Connect 関連仕様まとめ > 24. リクエストオブジェクト~ https://qiita.com/TakahikoKawasaki/items/185d34814eb9f7ac7ef3#24-%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88 ---- Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]