「[[マイクロソフト系技術情報 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 を参考にして作成。
-[[F-API2>FAPI Part 2 (Read and Write API Security Profile)#ha94c6d8]]でのユースケースは限定的で分かり易いが、~
こちらのフルスペックは若干意味不明(私が理解できていないダケ)。

--通信の送信元が認証されていない。
**弱点 [#md2aded4]
以下の弱点のために、

--TLS末端は保護されないため、パラメタ汚染、通信監視が可能。
---TLSセッションは、UserAgentで終了する。
---TLSセッションは、ロードバランサなど(ミドルボックス)で時期尚早に終了することがある。
-通信の送信元が認証されていない。

-対策として、認可リクエストのパラメタ群を[[JWT]]で送信する~
-TLS末端は保護されないため、パラメタ汚染、通信監視が可能。
--TLSセッションは、UserAgentで終了する。
--TLSセッションは、ロードバランサなど(ミドルボックス)で時期尚早に終了することがある。

**攻撃 [#s0e182ac]
以下の攻撃が可能。

-Redirect URI書き換え攻撃
-ミックスアタック攻撃[FETT]

**対策 [#j0e1699d]
対策として、認可リクエストのパラメタ群を[[JWT]]で送信する~
(認証要求に署名し、オプションで暗号化できる。)~
本[[OAuth 2.0 拡張]]が[[OpenID Connect]]によって追加された。

-これにより、許可要求の機密性、完全性が達成される。
**効果 [#d046bbb6]
このアプリケーション層セキュリティの使用により、
-許可要求の機密性、完全性が達成され、
-これらの問題が緩和される。

※ このページは、ドラフト 15 を参考にして作成。
**サード・パーティー [#m5a17a21]
本仕様(コンテキスト)中で、「サード・パーティー」という用語は、以下に関連する。
-[[Assertion Created by Third Party>JWT bearer token authorizationグラント種別#vf7e7da7]]
-[[Self-Issued Assertion>JWT bearer token authorizationグラント種別#n8fdd9f7]]
*Requestオブジェクト [#l71999b4]

*詳細 [#l71999b4]
**内容 [#vb813dbf]
[[JWT]]化された認可リクエストのパラメタ群をRequestオブジェクトと呼ぶ。

**Requestオブジェクト [#vb813dbf]
-[[JWT]]化された認可リクエストのパラメタ群をRequestオブジェクトと呼ぶ。
-Requestオブジェクトは、[[JWS]]で署名し、[[JWE]]で暗号化する。
***生成方法 [#ra39c605]
-Requestオブジェクト([[JWT]])は、
--[[JWS]]で署名し、
--必要に応じて[[JWE]]で暗号化する。

**Requestオブジェクトの渡し方 [#cf64a89f]
Requestオブジェクトの渡し方には以下の2つの方法がある。
-署名と暗号化が必要な場合、
--署名の後、暗号化を行う(逆はダメ)。
--詳しくは[[[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オブジェクトの値を直接渡す。

***request_uri パラメタ [#lcb4340f]
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パラメタ [#n1b24738]
下記手順でrequestパラメタからRequestオブジェクトを取得する。
下記手順で取得したRequestオブジェクトを署名検証(若しくは復号)する。

-・・・
**サード・パーティー [#g5378246]
この章に書かれている「jwks_uriにJWK Setを公開」する実装例は、
-[[サード・パーティー>#m5a17a21]]に依る「Assertion Created by Third Party」実装の場合か?~
-Clientに依る場合、「Self-Issued Assertion」実装で良い気がする。

***request_uriパラメタ [#mae51aa7]
下記手順でrequest_uriパラメタからRequestオブジェクトを取得する。
**復号化 [#c69daf29]
Requestオブジェクトが暗号化されている場合、~
下記手順で取得したRequestオブジェクトを復号化する。

-・・・
***復号化の処理 [#t8fedcf6]

***Requestオブジェクトの復号 [#c69daf29]
下記手順で取得したRequestオブジェクトを複合する。
-Requestオブジェクトの復号用の鍵を取得。~
クライアント・メタデータの登録・有無によってシーケンスが異なる。

-Requestオブジェクトの署名・検証(若しくは復号)用の鍵を取得。~
・・・クライアント・メタデータが、
--登録されている場合、~
JWK Setをjwks クライアントメタデータ値から取得。
[[JWK Set>JWK#od5799a4]]をjwks クライアントメタデータ値から取得。

--登録されていない場合、~
jwks_uriからクライアント・メタデータ(JWK Set)を取得。
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]
-The OAuth 2.0 Authorization Framework:~
JWT Secured Authorization Request (JAR)~
-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: [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]
Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]


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