コンテンツにスキップ

PAR

PAR(RFC 9126)は、クライアントがユーザーをリダイレクトする前に、認可リクエストパラメータを直接認可サーバーにプッシュできるOAuth 2.0セキュリティ拡張です。

  1. パラメータ改ざん防止

    • 認可パラメータはセキュアなバックチャネル経由で送信
    • ユーザーや中間者によるパラメータ変更不可
    • リクエストの整合性を保証
  2. プライバシー保護

    • 機密パラメータがブラウザ履歴に露出しない
    • リファラーヘッダーからの漏洩なし
    • 認可リクエストの監視を防止
  3. URL長制限の回避

    • ブラウザ/サーバーのURL長制限を回避
    • 多数のパラメータを持つ複雑なリクエストが可能
    • 大きなリクエストオブジェクト(JAR)をサポート
  4. クライアント認証

    • PARエンドポイントでクライアント認証を要求可能
    • 不正な認可リクエストを防止
    • フィッシングリスクを軽減
  • 金融サービス(FAPI準拠)
  • ヘルスケア(HIPAA準拠OAuthフロー)
  • エンタープライズ(多数のパラメータを持つ複雑な認可)
  • モバイルアプリ(ネイティブアプリからのセキュアな認可)
  1. クライアントがパラメータをプッシュ: クライアントが認可パラメータをPARエンドポイントに送信
  2. サーバーがパラメータを保存: サーバーが検証して保存(10分TTL)
  3. サーバーがrequest_uriを返却: サーバーが一意のrequest_uriで応答
  4. クライアントがユーザーをリダイレクト: クライアントがrequest_uri付きで認可エンドポイントにリダイレクト
  5. サーバーがパラメータを取得: 認可エンドポイントが保存されたパラメータを取得
  6. 通常のフローを継続: 認可が通常通り進行

POST /par

POST /par HTTP/1.1
Content-Type: application/x-www-form-urlencoded
Authorization: Basic <base64(client_id:client_secret)>
client_id=my_client_id
&response_type=code
&redirect_uri=https://myapp.example.com/callback
&scope=openid+profile+email
&state=abc123
&nonce=xyz789
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256

ステータス: 201 Created

{
"request_uri": "urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c",
"expires_in": 600
}
フィールド説明
request_uristring保存されたリクエストを識別する一意のURN
expires_innumber有効期間(秒)(デフォルト: 600 = 10分)

PARを使用した認可エンドポイント

Section titled “PARを使用した認可エンドポイント”

GET /authorize

GET /authorize
?request_uri=urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c
&client_id=my_client_id
Host: auth.example.com
パラメータ必須説明
request_uriYesPARレスポンスからのrequest URI
client_idYesPARリクエストのclient_idと一致する必要がある

Step 1: 認可リクエストをプッシュ

Section titled “Step 1: 認可リクエストをプッシュ”
Terminal window
curl -X POST https://auth.example.com/par \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=my_client_id" \
-d "response_type=code" \
-d "redirect_uri=https://myapp.example.com/callback" \
-d "scope=openid profile email" \
-d "state=abc123" \
-d "nonce=xyz789"

レスポンス:

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

Step 2: ユーザーを認可エンドポイントにリダイレクト

Section titled “Step 2: ユーザーを認可エンドポイントにリダイレクト”
const authUrl = new URL('https://auth.example.com/authorize');
authUrl.searchParams.set('request_uri', 'urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c');
authUrl.searchParams.set('client_id', 'my_client_id');
window.location.href = authUrl.toString();
GET /authorize
?response_type=code
&client_id=my_client_id
&redirect_uri=https://myapp.example.com/callback
&scope=openid+profile+email
&state=abc123

問題点:

  • パラメータがURLに露出
  • ブラウザ履歴に残る
  • URL長に制限
  • 改ざん可能
POST /par → {request_uri}
GET /authorize?request_uri=urn:ietf:...&client_id=my_client_id

利点:

  • パラメータはPOSTでセキュアに送信
  • ブラウザ履歴に残らない
  • URL長制限なし
  • 改ざん不可
  1. 単一使用: request_uriは取得後すぐに削除
  2. 短い有効期間: デフォルト10分(600秒)
  3. client_IDマッチング: 認可リクエストのclient_idはPARリクエストと一致する必要がある
  4. セキュアストレージ: パラメータは自動有効期限付きでKVに保存
  • FAPI 2.0: FAPI 2.0準拠にPAR必須
  • OAuth 2.1スタイルの構成: リクエスト完全性を高めるためにPARを推奨
  • OpenID Connect: すべてのOIDCフローと互換