- 追加された行はこの色です。
- 削除された行はこの色です。
「[[マイクロソフト系技術情報 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セッションは、ロードバランサなど(ミドルボックス)で時期尚早に終了することがある。
**攻撃 [#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: [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]
Tags: [[:IT国際標準]], [[:認証基盤]], [[:クレームベース認証]], [[:OAuth]]