「[[マイクロソフト系技術情報 Wiki>http://techinfoofmicrosofttech.osscons.jp/]]」は、「[[Open棟梁Project>https://github.com/OpenTouryoProject/]]」,「[[OSSコンソーシアム .NET開発基盤部会>https://www.osscons.jp/dotNetDevelopmentInfrastructure/]]」によって運営されています。

-[[戻る>JWTとOAuth2.0#bdaa0ed5]]
-戻る
--[[JWTとOAuth2.0 > クライアント認証>JWTとOAuth2.0#bdaa0ed5]]
--[[OpenID Connect - Requestオブジェクト]]
--[[FAPI Part 2 (Read and Write API Security Profile)]]

* 目次 [#l3592235]
#contents

*概要 [#r41f749f]
※ このページは、ドラフト 15 を参考にして作成。
-このページは、ドラフト 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オブジェクトの値を直接渡す。

-認可エンドポイント
 GET /authz?request=eyJhbG..AlMGzw HTTP/1.1
 Host: server.example.com
 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」エラーを返す。
復号化に失敗した場合、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を取得する。

-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で暗号化すべき。
ClientはRequestオブジェクトを[[JWE]]で暗号化すべき。

--request_uriパラメタ
---[[上記の考慮事項>#s5ba22a4]]を加味すべき。
---RequestオブジェクトをJWEで暗号化すべき。
---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

*?? [#nd472710]
(d)  (collection minimization) The request can be signed by a third party attesting that the authorization request is compliant with a certain policy.  For example, a request can be pre-examined by a third party that all the personal data requested is strictly necessary to perform the process that the end-user asked for, and statically signed by that third party.  The authorization server then examines the signature and shows the conformance status to the end-user, who would have some assurance as to the legitimacy of the request when authorizing it.  In some cases, it may even be desirable to skip the authorization dialogue under such circumstances.

----
Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]


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