OpenID Connect RP-Initiated Logout 1.0
RP-Initiated Logout は、Relying Party(RP)から OpenID Provider(OP)にログアウトを要求するための仕様です。
第1部: 概要編
RP-Initiated Logout とは?
RP-Initiated Logout は、ユーザーが RP のアプリケーションで「ログアウト」ボタンをクリックした際に、OP のセッションも終了させるための仕組みです。
RP-Initiated Logout のフロー:
┌────────────┐ ログアウト ┌────────────┐
│ ユーザー │ ───────────────► │ RP │
│ ブラウザ │ │ │
│ │ ◄──────────────── │ │
│ │ OP へリダイレクト │ │
└────────────┘ └────────────┘
│
│ GET /logout?id_token_hint=...&post_logout_redirect_uri=...
▼
┌────────────┐
│ OP │ セッション終了
│ │ ↓
│ │ post_logout_redirect_uri へリダイレクト
└────────────┘
│
▼
┌────────────┐
│ RP │ ログアウト完了画面
└────────────┘
他のログアウト仕様との違い
| 観点 | RP-Initiated | Front-Channel | Back-Channel |
|---|---|---|---|
| 起点 | RP | OP | OP |
| 目的 | OP セッション終了 | 複数 RP 同時ロ グアウト | 複数 RP 同時ログアウト |
| 通信 | ブラウザリダイレクト | iframe | サーバー間 |
| 信頼性 | 高い | 低い | 高い |
ログアウトの全体像:
ユーザー ──► RP「ログアウト」
│
▼
RP-Initiated Logout
│
▼
OP セッション終了
│
┌─────┴─────┐
▼ ▼
Front-Channel Back-Channel
(iframe通知) (サーバー通知)
│ │
▼ ▼
他の RP 他の RP
第2部: 詳細編
エンドポイント
GET /logout?
id_token_hint=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
&post_logout_redirect_uri=https://rp.example.com/logout/callback
&state=abc123
&client_id=s6BhdRkqt3
リクエストパラメータ
| パラメータ | 仕様 | idp-server | 説明 |
|---|---|---|---|
id_token_hint | RECOMMENDED | REQUIRED | 以前発行された ID Token。ユーザー識別に使用 |
client_id | OPTIONAL | OPTIONAL | クライアント識別子 |
post_logout_redirect_uri | OPTIONAL | OPTIONAL | ログ アウト後のリダイレクト先 |
state | OPTIONAL | OPTIONAL | CSRF 対策用の状態値 |
logout_hint | OPTIONAL | - | ログアウト対象のヒント(OP 裁量) |
ui_locales | OPTIONAL | OPTIONAL | UI の言語設定 |
Note: idp-server では
id_token_hintを必須としています。詳細は「第5部: idp-server の実装ポリシー」を参照してください。
id_token_hint の役割
id_token_hint が重要な理由:
1. ユーザー識別
JWT の sub claim からユーザーを特定
2. クライアント識別
JWT の aud claim から クライアントを特定
3. セッション識別
JWT の sid claim からセッションを特定(オプション)
4. セキュリティ
正当なリクエストであることの証明
クライアント識別の優先順位
クライアント識別の優先順位:
1. client_id パラメータ(明示的に指定)
↓ なければ
2. id_token_hint の aud claim
↓ なければ
3. クライアント識別不可
id_token_hint がない場合の処理
仕様では、id_token_hint がない場合の OP の動作について重要な規定があります:
"the OP MUST ask the End-User this question if an id_token_hint was not provided or if the supplied ID Token does not belong to the current OP session"
id_token_hint の有無による処理の違い:
id_token_hint あり
↓
ユーザー・セッション特定可能
↓
自動ログアウト(確認不要)
↓
post_logout_redirect_uri へリダイレクト
id_token_hint なし
↓
誰のリクエストか不明
↓
ユーザーに確認を求める(MUST)
「ログアウトしますか?」
↓
ユーザーが承認 → ログアウト実行
この確認が必要な理由:
攻撃シナリオ: DoS によるログアウト強制
1. 攻撃者が悪意あるサイトを作成
2. 隠し iframe で OP の logout エンドポイントに誘導
3. id_token_hint なし(攻撃者は持っていない)
確認なしの場合:
→ ユーザーが知らないうちにログアウトされる
確認ありの場合:
→ 「ログアウトしますか?」画面が表示
→ ユーザーが気づく → 攻撃失敗
post_logout_redirect_uri の検証
post_logout_redirect_uri が指定された場合、OP は必ず検証を行う必要があります。
post_logout_redirect_uri の検証フロー:
1. クライアント識別可能か?
- client_id または id_token_hint.aud から識別
- 識別不可 → エラー(400 Bad Request)
2. クライアントに登録済みか?
- post_logout_redirect_uris に完全一致で存在するか
- 未登録 → エラー(400 Bad Request)
3. 検証成功
- ログアウト後にリダイレクト
仕様の引用:
"This URI MUST have been previously registered with the OP, either using the post_logout_redirect_uris Registration parameter or via another mechanism."
オープンリダイレクト攻撃の防止:
攻撃シナリオ:
GET /logout?
id_token_hint=valid_token
&post_logout_redirect_uri=https://evil.com/phishing
対策:
事前登録された URI のみ許可
完全一致(ワイルドカード不可)
state パラメータ
state の役割:
1. RP → OP へのリクエスト
GET /logout?
id_token_hint=...
&post_logout_redirect_uri=https://rp.example.com/callback
&state=xyz789
2. OP → RP へのリダイレクト
GET https://rp.example.com/callback?
state=xyz789
3. RP での検証
- セッションに保存した state と比較
- 一致しなければ不正なリクエスト
クライアント登録
RP は登録時に post_logout_redirect_uris を指定します。
{
"client_id": "s6BhdRkqt3",
"redirect_uris": ["https://rp.example.com/callback"],
"post_logout_redirect_uris": [
"https://rp.example.com/logout/callback",
"https://rp.example.com/signed-out"
]
}