MS_JAR - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- 戻る(JWTとOAuth2.0、OpenID Connect - Requestオブジェクト、FAPI Part 2)
- JWT Secured Authorization Request (JAR)
- JARM(レスポンス版)
- このページは、ドラフト 15 を参考にして作成。
-
FAPI2でのユースケースは限定的で分かり易いが、
こちらのフルスペックは若干意味不明(私が理解できていないダケ)。
移行メモ(最新化): 本ページ執筆時はドラフトだったが、
2023年8月に RFC 9101 として標準化された。
内容はドラフト末期からほぼ変わっていない。
以下の弱点のために、
- 通信の送信元が認証されていない。
-
TLS 末端は保護されないため、パラメタ汚染、通信監視が可能。
- TLS セッションは、UserAgent で終了する。
- TLS セッションは、ロードバランサなど(ミドルボックス)で
時期尚早に終了することがある。
以下の攻撃が可能。
- Redirect URI 書き換え攻撃
- ミックスアップ攻撃(IdP Mix-Up)
対策として、認可リクエストのパラメタ群を JWTで送信する
(認証要求に署名し、オプションで暗号化できる)。
本 OAuth 2.0 拡張が
OpenID Connectによって追加された。
このアプリケーション層セキュリティの使用により、
- 許可要求の機密性、完全性が達成され、
- これらの問題が緩和される。
補足(OIDC の Request オブジェクトとの関係): 中身は
ほぼ同じものである。違いは位置づけにある。
OIDC Request オブジェクト JAR(RFC 9101) 定義元 OpenID Connect Core 1.0 の一節 独立した RFC 前提 OIDC( scope=openidが要る)素の OAuth 2.0 でも使える alg: none可 禁止(署名必須) client_idRequest オブジェクト内 外側にも必須(AS が鍵を探すため) 「OIDC の一機能」だったものを、
OAuth 2.0 全体で使える独立仕様に切り出したのが JAR である。
FAPIが OIDC 非依存でも使えるようにするために必要だった。
本仕様(コンテキスト)中で、「サード・パーティー」という用語は、
以下に関連する(JWT bearer token authorization グラント種別)。
- Assertion Created by Third Party
- Self-Issued Assertion
JWT化された認可リクエストのパラメタ群を Request オブジェクトと呼ぶ。
補足(順序が決まっている理由): 「署名 → 暗号化」の順でなければ
ならないのは、逆にすると署名が何を保証しているか不明になるためである。
順序 意味 署名 → 暗号化(正) 「この平文の内容を私が承認した」 暗号化 → 署名(誤) 「この暗号文を私が転送した」(中身を見ていない可能性) 後者では、第三者が作った暗号文に署名を付け替えるだけで
「自分が作った」ように見せられてしまう。
RFC 7519 の 11.2 節にも同じ指針がある。
- 合意した以上のアクセス権を要求できないようにすることで、
プライバシーを保護する。 - この場合、認可プロンプトをスキップすることが望ましい場合もある。
- 以下のような少数例にも適合する。
- 送信される要求のサイズを小さくすることが望ましい場合。
- Client が暗号を行いたくないとき(JWSで署名し、TLS を使用する)。
Request オブジェクト(JWT)のペイロードを base64url デコードした文字列。
認可 Request の全てのパラメタが Request オブジェクトに同梱されている。
ヘッダ(共通):
{
"alg": "RS256",
"kid": "k2bdc"
}ペイロード(通常):
{
"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を参照)。
| 方法 | 内容 |
|---|---|
request |
Request オブジェクト(JWT)を値として直接渡す |
request_uri |
Request オブジェクトを置いた URLを渡す(AS が取りに行く) |
補足(URL 長の壁):
requestパラメタは JWT をそのまま URL に載せるため、
数 KB になることがある。
環境 URL 長の実質上限 古い IE 2,083 文字 一般的なブラウザ 数万文字(実装依存) サーバー / プロキシ 8KB 前後で 414 を返す実装が多い
claimsを多く含めるとすぐ超えるため、
request_uri方式、さらには PAR(RFC 9126) へと発展した
(OpenID Connect - Requestオブジェクトの補足を参照)。
補足(
request_uriの SSRF リスク):request_uri方式では
Authorization Server が Client の指定した URL を取りに行く。
制限しないと SSRF(Server-Side Request Forgery) の入口になる。
対策 内容 事前登録( request_uris)取りに行く先を登録済みのものに限定 プライベート IP の拒否 169.254.169.254(クラウドのメタデータ)等を弾くリダイレクトの追跡を制限 302 で内部に誘導されるのを防ぐ タイムアウト・サイズ制限 DoS 対策 PAR はこの方向を逆転させ(Client が push する)、
SSRF の懸念自体を消している。これが FAPI 2.0 で PAR が
必須になった理由の一つである。
補足(
client_idは外側にも必要): Request オブジェクトを
検証するには、まず署名鍵を特定する必要がある。
しかし鍵は「どの Client か」が分からないと選べない。このため JAR(RFC 9101)では、
client_idは Request オブジェクトの外側(クエリ パラメタ)にも必須と定めている。「中身を検証する前に、外側だけで鍵を引ける」
ようにするための設計である。
-
RFC 9101 - The OAuth 2.0 Authorization Framework: JWT-Secured Authorization Request (JAR)
https://datatracker.ietf.org/doc/html/rfc9101 -
RFC 9126 - OAuth 2.0 Pushed Authorization Requests (PAR)
https://datatracker.ietf.org/doc/html/rfc9126
Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth