Skip to content
nishi_74322014 edited this page Sep 1, 2026 · 1 revision

JWT Secured Authorization Request (JAR)

概要

  • このページは、ドラフト 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
前提 OIDCscope=openid が要る) 素の OAuth 2.0 でも使える
alg: none 禁止(署名必須)
client_id Request オブジェクト内 外側にも必須(AS が鍵を探すため)

「OIDC の一機能」だったものを、
OAuth 2.0 全体で使える独立仕様に切り出したのが JAR である。
FAPIが OIDC 非依存でも使えるようにするために必要だった。

サード・パーティー

本仕様(コンテキスト)中で、「サード・パーティー」という用語は、
以下に関連する(JWT bearer token authorization グラント種別)。

  • Assertion Created by Third Party
  • Self-Issued Assertion

Requestオブジェクト

内容

JWT化された認可リクエストのパラメタ群を Request オブジェクトと呼ぶ。

生成方法

  • Request オブジェクト(JWT)は、
    • JWSで署名し、
    • 必要に応じて JWEで暗号化する。
  • 署名と暗号化が必要な場合、署名の後、暗号化を行う(逆はダメ)。

補足(順序が決まっている理由): 「署名 → 暗号化」の順でなければ
ならないのは、逆にすると署名が何を保証しているか不明になるためである。

順序 意味
署名 → 暗号化(正) この平文の内容を私が承認した」
暗号化 → 署名(誤) 「この暗号文を私が転送した」(中身を見ていない可能性)

後者では、第三者が作った暗号文に署名を付け替えるだけで
「自分が作った」ように見せられてしまう。
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 オブジェクトの外側(クエリ パラメタ)にも必須

と定めている。「中身を検証する前に、外側だけで鍵を引ける」
ようにするための設計である。

参考

関連仕様


Tags: 移行, IT国際標準, 認証基盤, クレームベース認証, OAuth

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally