メインコンテンツまでスキップ

OpenID Connect Front-Channel Logout 1.0

Front-Channel Logout は、ブラウザのリダイレクトを利用して複数の RP を同時にログアウトするための仕様です。


第1部: 概要編

Front-Channel Logout とは?

Front-Channel Logout は、ユーザーのブラウザ(フロントチャネル)を通じて、OP から各 RP にログアウトを通知する仕組みです。

Front-Channel Logout のフロー:

┌────────────┐ ログアウト ┌────────────┐
│ ユーザー │ ───────────────► │ OP │
│ ブラウザ │ │ │
│ │ ◄──────────────── │ │
│ │ ログアウトページ │ │
└────────────┘ └────────────┘

│ iframe で各 RP のログアウト URL を読み込み

┌─────────────────────────────────────────────┐
│ OP のログアウトページ │
│ ┌─────────────────────────────────────────┐ │
│ │ <iframe src="https://rp1/logout"> │ │
│ │ <iframe src="https://rp2/logout"> │ │
│ │ <iframe src="https://rp3/logout"> │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────┘

Back-Channel との違い

観点Front-ChannelBack-Channel
通信経路ブラウザ経由サーバー間直接
信頼性低い(ブラウザ依存)高い
Cookie利用可能利用不可
実装シンプル複雑
スケールRP 数に制限あり制限なし

第2部: 詳細編

クライアント登録

RP は登録時に Front-Channel Logout URI を指定します。

{
"client_id": "s6BhdRkqt3",
"redirect_uris": ["https://rp.example.com/callback"],
"frontchannel_logout_uri": "https://rp.example.com/logout/frontchannel",
"frontchannel_logout_session_required": true
}
メタデータ説明
frontchannel_logout_uriRP のログアウトエンドポイント
frontchannel_logout_session_requiredsid を含めるか

OP のログアウトページ

ユーザーがログアウトすると、OP は各 RP の frontchannel_logout_uri を iframe で読み込むページを表示します。

<!-- OP のログアウトページ -->
<!DOCTYPE html>
<html>
<head>
<title>Logging Out...</title>
<style>
.logout-container { text-align: center; padding: 50px; }
.logout-status { margin: 20px 0; }
iframe { display: none; }
</style>
</head>
<body>
<div class="logout-container">
<h1>ログアウト中...</h1>
<div class="logout-status" id="status">
各アプリケーションからログアウトしています
</div>

<!-- 各 RP の logout iframe -->
<iframe id="rp1" src="https://rp1.example.com/logout/frontchannel?iss=https://op.example.com&sid=abc123"></iframe>
<iframe id="rp2" src="https://rp2.example.com/logout/frontchannel?iss=https://op.example.com&sid=abc123"></iframe>
<iframe id="rp3" src="https://rp3.example.com/logout/frontchannel?iss=https://op.example.com&sid=abc123"></iframe>
</div>

<script>
var iframes = document.querySelectorAll('iframe');
var loaded = 0;
var total = iframes.length;

iframes.forEach(function(iframe) {
iframe.onload = function() {
loaded++;
if (loaded === total) {
// すべての RP がログアウト完了
document.getElementById('status').textContent = 'ログアウト完了';

// post_logout_redirect_uri にリダイレクト
setTimeout(function() {
window.location.href = 'https://rp1.example.com/logout/callback';
}, 1000);
}
};

iframe.onerror = function() {
loaded++;
console.error('Logout failed for:', iframe.src);
};
});

// タイムアウト
setTimeout(function() {
if (loaded < total) {
document.getElementById('status').textContent =
'一部のアプリケーションからのログアウトに失敗しました';
}
}, 5000);
</script>
</body>
</html>

RP のログアウトエンドポイント

GET https://rp.example.com/logout/frontchannel?
iss=https://op.example.com
&sid=abc123
パラメータ説明
issOP の識別子
sidセッション ID(オプション)

JavaScript(RP 側)

ディスカバリーメタデータ

{
"issuer": "https://op.example.com",
"frontchannel_logout_supported": true,
"frontchannel_logout_session_supported": true
}
メタデータ説明
frontchannel_logout_supportedFront-Channel Logout をサポート
frontchannel_logout_session_supportedsid パラメータをサポート

セキュリティ考慮事項

項目推奨事項
iss の検証信頼された OP からのリクエストのみ処理
HTTPSログアウト URI は HTTPS 必須
Cache-Controlキャッシュを無効化
Cookie 属性SameSite=None, Secure が必要
タイムアウトiframe の読み込みにタイムアウトを設定

制限事項

Front-Channel Logout の制限:

1. ブラウザの制限
- サードパーティ Cookie のブロック
- ITP(Safari)
- Enhanced Tracking Prevention(Firefox)

2. iframe の制限
- X-Frame-Options
- Content-Security-Policy

3. 信頼性
- ブラウザを閉じると実行されない
- ネットワーク遅延の影響

推奨:
- Back-Channel Logout と併用
- 重要なセッションは Back-Channel を使用

参考リンク