呼叫 OpenID Connect 的階段作業管理端點

階段作業管理端點可讓「OpenID Connect 依賴方」監視使用者在特定「OpenID Connect 提供者 (OP)」的登入狀態,同時將網路資料流量降至最低。藉助於階段作業管理端點,「依賴方 (RP)」可以使已登出「OpenID Connect 提供者」的使用者登出。

開始之前

會從 check_session_iframe 屬性,取得 OP 階段作業管理端點 URL,該屬性位於 OP 探索端點傳回的探索資訊中。在需要階段作業管理功能的 RP 應用程式中,此 URL 必須作為 iframe 的目標。RP 應用程式也必須知道 iframeid 屬性,以便提交 Window.postMessage() 要求給它。

關於這項作業

為了有助於判斷使用者的登入狀態,RP 會載入 iframe,且其中的 src 目標是設為 OP 的階段作業管理端點。階段作業管理端點有權存取儲存了使用者登入狀態或瀏覽器狀態的 Cookie。當使用者登出 OP 時,會更新此瀏覽器狀態 Cookie。接著,RP 可以使用用戶端 Scripting,來呼叫 OP iframeWindow.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
避免問題: 如果您使用出埠 Proxy,請注意, OpenID Connect RP 不提供任何方法來自動透過 Proxy 主機遞送要求。

如果您必須使用 Proxy 來存取「OpenID Connect 提供者 (OP)」,您針對任何 OP 相關 URL 內容所輸入的值,必須包含 Proxy 主機和埠,而不是包含外部 OP 主機和埠。

在大部分情況下,您可以用 Proxy 主機和埠,取代 OP 主機和埠。RP 和用戶端(瀏覽器或應用程式)必須都能看見您所輸入的 URL。對於如何判斷所要使用的正確 URL,如需進一步指引,請聯絡您的 Proxy 管理者。

在本例中,用戶端預期的 SSL 埠設為 443。

程序

  1. 在能夠載入 iframe,並以 OP 階段作業管理端點為目標的適當 RP 應用程式中,建立 Web 資源。Web 資源也需要能夠存取授權回應 session_state 參數中所傳回的階段作業狀態值。階段作業狀態值可以儲存在 Cookie 中,或者比方說,以可讓 Web 資源中的用戶端 Scripting 知道此值為何的其他任何方式。以下是這類 iframe 的範例 HTML Snippet。
    <iframe id="iframeOP" src="https://server.example.com:443/oidc/endpoint/OidcConfigSample/check_session_iframe" frameborder="0" width="0" height="0"></iframe>
  2. 為了檢查使用者的登入狀態,請呼叫 OP iframeWindow.postMessage() 函數,這會以訊息參數形式傳遞用戶端 ID 和階段作業狀態(格式是 Client ID + " " + Session State),並且以目標發送端參數形式傳遞 OP 的主機名稱。在下列的 JavaScript 範例函數中,Script 預期階段作業狀態值儲存在名稱是 session_state 的 Cookie 中,且 getCookieValue() 函數會傳回儲存在 session_state Cookie 中的值。
    	var targetOP = "https://server.example.com:443";
    	function checkStatus() {
               var client = "client01";
               var sessionState = getCookieValue("session_state");
               var text = client + " " + sessionState;
               var iframe = document.getElementById("iframeOP");
               iframe.contentWindow.postMessage(text, targetOP);
    	}
  3. 將 Web 資源配置成接聽來自 OP 的 postMessages,且其中含有值 changedunchanged,以反映使用者個別的登入狀態。接著,RP 就可根據 OP 傳回的值,來決定是否讓使用者登出 RP。此函數必須確定 postMessage 發送端符合預期的 OP 主機名稱。會拒絕任何不符合的訊息。下列 JavaScript 範例顯示如何新增事件接聽器至 Web 資源,以接聽這類訊息。
    	var targetOP = "https://server.example.com:443";
    	window.addEventListener("message", receiveMessage, false);
    	function receiveMessage(event) {
               if (event.origin !== targetOP) {
                         // Origin did not come from the OP; this message must be rejected.
                         return;
               }
               if (event.data === "unchanged") {
                         // User is still logged in to the OP
               } else {
                         // User has logged out of the OP
               }
    	}

結果

現在您在 RP 上有一個 Web 資源,它能夠利用 Liberty 伺服器 OP 上的 OpenID Connect 階段作業管理功能。當使用者登入或登出 OP 時,會更新 OP iframe 中所維護的瀏覽器狀態。在順利登入 OP 之後,會在傳給 RP 的授權回應中提供新的階段作業狀態值。接著,RP 可以使用用戶端 Scripting,來驗證使用者的階段作業狀態,以判斷使用者在 OP 上的登入狀態是否已變更,而這並不需要播送額外的網路資料流量。

範例

下列 HTML 範例顯示使用「OpenID Connect 階段作業管理」的完整 HTML 頁面。OP iframesrc 屬性設為從 OP 取得的階段作業管理端點 URL。每 60 秒會自動呼叫 startChecking() 函數,並檢查使用者的登入狀態。頁面有一個 message 事件接聽器,當收到 postMessage 時,它會呼叫 receiveMessage() 函數。此函數確定 postMessage 是來自預期的 OP 網域,它會檢查回覆訊息的值,看看使用者的登入狀態是 changedunchanged

您可以載入這個 HTML 頁面本身,以便在 RP 的另一個 Web 資源中,作為不可見的 iframe。如此一來,只要 Web 資源載入這個 iframe,就可以在用戶端監視使用者的登入狀態。
	<!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();
                      // Check status every 60 seconds
                      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) {
                                // Origin did not come from the OP; this message must be rejected
                                return;
                      }
                      if (event.data === "unchanged") {
                                // User is still logged in to the OP
                      } else {
                                // User has logged out of the OP
                      }
            }
	</script>
	</html>

指示主題類型的圖示 作業主題

檔名:twlp_oidc_session_mgmt_endpoint.html