Open3

RFC 9126 OAuth 2.0 Pushed Authorization Requests

yapooyapoo

RFC 9126 - OAuth 2.0 Pushed Authorization Requests

仕様の中で PAR と略されている。

概要

RFC 6749 で定義された認可エンドポイントの仕様には以下の問題がある

  • 暗号的な完全性やクライアント認証の仕組みがない
  • 認可エンドポイントはユーザーエージェントからリクエストされるものであり、リクエストパラメータの機密性を守る仕組みがない
  • クエリパラメータによって URL が非常に長くなる可能性がある

PAR は以下の手順によって上記の (暗号的な完全性を除いた) 問題の解決を目指す [1]。仕様の肝は認可エンドポイントのパラメータを認可サーバーにあらかじめ登録しておく点である。

最初に認可エンドポイントのリクエストパラメータを送信する際に、JAR (RFC 9101) の仕様に従って JWT を送ることもできる。こうすると認可エンドポイントへのリクエストのサイズを抑え、かつリクエストの完全性を達成しつつ、JWT の公開をせずにリクエストのサイズを減らすことができる。ただし後述するように、request パラメータで JWT を直接指定することはできるが、request_uri で JWT への参照を指定することはできない。

脚注
  1. JAR (RFC 9101) があればこちらは不要な気もするが、JWT の生成 (リクエストのサイズを抑えたい場合は公開も) をしなくてよい点でクライアントにとってこちらの仕様のほうがシンプルであるように思われる ↩︎

yapooyapoo

Pushed Authorization Request Endpoint

リクエスト

認可サーバーは PAR のためのエンドポイントを公開し、クライアントはここに POST リクエストを送る。パラメータは application/x-www-form-urlencoded で送信する必要がある。以下は Section 2.1 で示されるリクエストの例である。

POST /as/par HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded

response_type=code&state=af0ifjsldkj&client_id=s6BhdRkqt3
&redirect_uri=https%3A%2F%2Fclient.example.org%2Fcb
&code_challenge=K2-ltc83acc4h0c9w6ESC_rEMTJ3bww-uCHaoeK1t8U
&code_challenge_method=S256&scope=account-information
&client_assertion_type=
 urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJraWQiOiJrMmJkYyIsImFsZyI6IlJTMjU2In0.eyJpc3Mi
 OiJzNkJoZFJrcXQzIiwic3ViIjoiczZCaGRSa3F0MyIsImF1ZCI6Imh0dHBzOi8vc
 2VydmVyLmV4YW1wbGUuY29tIiwiZXhwIjoxNjI1ODY5Njc3fQ.te4IdnP_DK4hWrh
 TWA6fyhy3fxlAQZAhfA4lmzRdpoP5uZb-E90R5YxzN1YDA8mnVdpgj_Bx1lG5r6se
 f5TlckApA3hahhC804dcqlE4naEmLISmN1pds2WxTMOUzZY8aKKSDzNTDqhyTgE-K
 dTb3RafRj7tdZb09zWs7c_moOvfVcQIoy5zz1BvLQKW1Y8JsYvdpu2AvpxRPbcP8W
 yeW9B6PL6_fy3pXYKG3e-qUcvPa9kan-mo9EoSgt-YTDQjK1nZMdXIqTluK9caVJE
 RWW0fD1Y11_tlOcJn-ya7v7d8YmFyJpkhZfm8x1FoeH0djEicXTixEkdRuzsgUCm6
 GQ

RFC 6749 では定義されない拡張パラメータを指定することも可能である。この例では PKCE (code_challengecode_challenge_method) [1]に加え、クライアント認証として JWT (client_assertion_typeclient_assertion) [2]を用いている。

認可サーバーは以下の処理を行わなければならない

  • トークンエンドポイントと同様のクライアント認証[3]を行う
  • リクエストパラメータに request_uri [4] が含まれる場合はリクエストを拒否する
  • 認可エンドポイントと同様のリクエストパラメータのバリデーション (client_id が指定されていることなど)

なお redirect_uri の検証にあたって RFC 6749 Section 3.1.2.2 では事前に登録したものと完全一致するべきであるとされているが、PAR においては事前に登録していない値を許可しても良い[5]

レスポンス

リクエストパラメータの検証結果が問題なかった場合、認可サーバーは短命の URI を発行し、その寿命とともにクライアントに返却する。ここで URI は urn:ietf:params:oauth:request_uri:(ランダム値) としてもよい。レスポンスボディは JSON で、ステータスコードは 201 とする。

以下は Section 2.2 に記載のレスポンスの例である。

HTTP/1.1 201 Created
Content-Type: application/json
Cache-Control: no-cache, no-store

{
 "request_uri": "urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c",
 "expires_in": 60
}

expires_in は秒単位で指定される。具体的な長さは認可サーバーで決めるが、典型的には短い値 (5~600 秒)とするようだ。

エラー時には、トークンエンドポイントと同様の形式のエラーレスポンスを返却する[6]が、エラーコードとしてはトークンエンドポイントや認可エンドポイント[7]で定義されているものを用いる。ただし、認可エンドポイントのエラーコードとして定義されていないものについては、invalid_request をデフォルトのエラーコードとして用いて良い。

これに加え、以下がエラー時のステータスコードとして定義されている:

Status Code Description
405 POST 以外のメソッドでリクエストされた場合
413 リクエストボディが大きすぎる場合
429 リクエストの頻度が高すぎる場合

以下は Section 2.3 で示されるエラーレスポンスの例である

HTTP/1.1 400 Bad Request
Content-Type: application/json
Cache-Control: no-cache, no-store

{
  "error": "invalid_request",
  "error_description": "The redirect_uri is not valid for the given client"
}
脚注
  1. RFC 7636 ↩︎

  2. RFC 7521RFC 7523 ↩︎

  3. RFC 6749 Section 2.3 ↩︎

  4. JAR (RFC 9101) で JWT の URI を指定する場合に使われるパラメータ ↩︎

  5. これは JAR でも同様に完全一致の制限は無くしても良いように思われるのだが、そのようには記載されていない ↩︎

  6. RFC 6749 Section 5.2 ↩︎

  7. RFC 6749 Section 4.1.2.1 ↩︎

yapooyapoo

認可エンドポイント

クライアントは Pushed Authorization Request Endpoint で受け取った request_uri を、(ユーザーエージェントを介して) 認可エンドポイントの request_uri パラメータを用いて認可サーバーに送信する。以下は Section 4 に記載のリクエストの例である

GET /authorize?client_id=s6BhdRkqt3&request_uri=urn%3Aietf%3Aparams
 %3Aoauth%3Arequest_uri%3A6esc_11ACC5bwc014ltc14eY22c HTTP/1.1
Host: as.example.com

クライアントは Pushed Authorization Request Endpoint で受け取った request_uri を 1 回しか用いてはならない。認可サーバーはエンドユーザーがリロード等をした場合に備えて、多重リクエストは許可しても良い。request_uri が失効している場合にはエラーを返却しなければならない。

認可サーバーは受け取ったリクエストのバリデーションをしなければならないが、Pushed Authorization Request Endpoint ですでに行ったバリデーションは省略しても良い。ただし Pushed Authorization Request Endpoint が行われてから認可エンドポイントのリクエストまでの間に生じた認可サーバーまたはクライアントの設定の変更によってバリデーション結果が変化するような場合には、再度のバリデーションをしなければならない。