呼叫 OpenID Connect 的階段作業管理端點
階段作業管理端點可讓「OpenID Connect 依賴方」監視使用者在特定「OpenID Connect 提供者 (OP)」的登入狀態,同時將網路資料流量降至最低。藉助於階段作業管理端點,「依賴方 (RP)」可以使已登出「OpenID Connect 提供者」的使用者登出。
開始之前
關於這項作業
為了有助於判斷使用者的登入狀態,RP 會載入 iframe,且其中的 src 目標是設為 OP 的階段作業管理端點。階段作業管理端點有權存取儲存了使用者登入狀態或瀏覽器狀態的 Cookie。當使用者登出 OP 時,會更新此瀏覽器狀態 Cookie。接著,RP 可以使用用戶端 Scripting,來呼叫 OP iframe 的 Window.postMessage() 函數,以便將用戶端 ID 和目前已知的階段作業狀態放在訊息文字中傳送。如果 RP 收到 OP 訊框傳回 postMessage,且其值是 changed,表示使用者在 OP 的登入狀態已變更,RP 可以決定是否要讓使用者登出。如果傳回的值是 unchanged,表示使用者在 OP 仍為登入狀態。
啟用 OpenID Connect 的 Liberty 伺服器能夠存取位於下列 URL 的 OpenID Connect 階段作業管理端點:
https://server.example.com:443/oidc/endpoint/<provider_name>/check_session_iframe
程序
結果
範例
下列 HTML 範例顯示使用「OpenID Connect 階段作業管理」的完整 HTML 頁面。OP iframe 的 src 屬性設為從 OP 取得的階段作業管理端點 URL。每 60 秒會自動呼叫 startChecking() 函數,並檢查使用者的登入狀態。頁面有一個 message 事件接聽器,當收到 postMessage 時,它會呼叫 receiveMessage() 函數。此函數確定 postMessage 是來自預期的 OP 網域,它會檢查回覆訊息的值,看看使用者的登入狀態是 changed 或 unchanged。
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>iFrame RP Page</title>
</head>
<body onload="javascript:startChecking()">
<iframe id="iframeOP" src="https://localhost:8999/oidc/endpoint/OidcConfigSample/check_session_iframe" frameborder="0" width="0" height="0"></iframe>
</body>
<script>
var targetOP = "https://server.example.com:443";
window.addEventListener("message", receiveMessage, false);
function startChecking() {
checkStatus();
// 每 60 秒就檢查狀態
setInterval("checkStatus()", 1000*60);
}
function getCookieValue(cookieName) {
var name = cookieName + "=";
var cookies = document.cookie.split(';');
if (!cookies) {
return null;
}
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.indexOf(name) == 0) {
return cookie.substring(name.length, cookie.length);
}
}
return null;
}
function checkStatus() {
var client = "client01";
var sessionState = getCookieValue("session_state");
var text = client + " " + sessionState;
var iframe = document.getElementById("iframeOP");
iframe.contentWindow.postMessage(text, targetOP);
}
function receiveMessage(event) {
if (event.origin !== targetOP) {
// 發送端不是來自 OP;必須拒絕此訊息
return;
}
if (event.data === "unchanged") {
// 使用者在 OP 仍為登入狀態
} else {
// 使用者已登出 OP
}
}
</script>
</html>