PAR
PAR (Pushed Authorization Requests)
PAR(RFC 9126)は、クライアントがユーザーをリダイレクトする前に、認可リクエストパラメータを直接認可サーバーにプッシュできるOAuth 2.0セキュリティ拡張です。
概要
- RFC: RFC 9126 - OAuth 2.0 Pushed Authorization Requests
- ステータス: 完全実装
- エンドポイント:
POST /as/par
なぜPARを使用するのか?
セキュリティ上の利点
-
パラメータ改ざん防止
- 認可パラメータはセキュアなバックチャネル経由で送信
- ユーザーや中間者によるパラメータ変更不可
- リクエストの整合性を保証
-
プライバシー保護
- 機密パラメータがブラウザ履歴に露出しない
- リファラーヘッダーからの漏洩なし
- 認可リクエストの監視を防止
-
URL長制限の回避
- ブラウザ/サーバーのURL長制限を回避
- 多数のパラメータを持つ複雑なリクエストが可能
- 大きなリクエストオブジェクト(JAR)をサポート
-
クライアント認証
- PARエンドポイントでクライアント認証を要求可能
- 不正な認可リクエストを防止
- フィッシングリスクを軽減
ユースケース
- 金融サービス(FAPI準拠)
- ヘルスケア(HIPAA準拠OAuthフロー)
- エンタープライズ(多数のパラメータを持つ複雑な認可)
- モバイルアプリ(ネイティブアプリからのセキュアな認可)
PARの仕組み
フロー概要
- クライアントがパラメータをプッシュ: クライアントが認可パラメータをPARエンドポイントに送信
- サーバーがパラメータを保存: サーバーが検証して保存(10分TTL)
- サーバーがrequest_uriを返却: サーバーが一意の
request_uriで応答 - クライアントがユーザーをリダイレクト: クライアントが
request_uri付きで認可エンドポイントにリダイレクト - サーバーがパラメータを取得: 認可エンドポイントが保存されたパラメータを取得
- 通常のフローを継続: 認可が通常通り進行
APIリファレンス
PARエンドポイント
POST /as/par
リクエスト形式
POST /as/par HTTP/1.1Content-Type: application/x-www-form-urlencodedAuthorization: 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_uri | string | 保存されたリクエストを識別する一意のURN |
expires_in | number | 有効期間(秒)(デフォルト: 600 = 10分) |
PARを使用した認可エンドポイント
GET /authorize
GET /authorize ?request_uri=urn:ietf:params:oauth:request_uri:6esc_11ACC5bwc014ltc14eY22c &client_id=my_client_idHost: auth.example.com| パラメータ | 必須 | 説明 |
|---|---|---|
request_uri | Yes | PARレスポンスからのrequest URI |
client_id | Yes | PARリクエストのclient_idと一致する必要がある |
使用例
基本的なPARフロー
Step 1: 認可リクエストをプッシュ
curl -X POST https://auth.example.com/as/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: ユーザーを認可エンドポイントにリダイレクト
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();従来方式とPARの比較
従来の認可リクエスト
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長に制限
- 改ざん可能
PAR認可リクエスト
POST /as/par → {request_uri}
GET /authorize?request_uri=urn:ietf:...&client_id=my_client_id利点:
- パラメータはPOSTでセキュアに送信
- ブラウザ履歴に残らない
- URL長制限なし
- 改ざん不可
セキュリティ機能
- 単一使用: request_uriは取得後すぐに削除
- 短い有効期間: デフォルト10分(600秒)
- client_IDマッチング: 認可リクエストの
client_idはPARリクエストと一致する必要がある - セキュアストレージ: パラメータは自動有効期限付きでKVに保存
準拠
- FAPI 2.0: FAPI 2.0準拠にPAR必須
- OAuth 2.1: PARはOAuth 2.1ドラフトの一部
- OpenID Connect: すべてのOIDCフローと互換