| 目錄 |
|
OpenID Connect 1.0 是 OAuth 2.0 協議之上的簡單身份層。它使客戶端能夠根據授權服務器執行的身份驗證來驗證最終用戶的身份,并以可互操作和REST 風格的方式獲取有關最終用戶的基本資料信息。
本文檔介紹如何管理 OpenID Connect 會話,包括何時注銷最終用戶。
1.
簡介
1.1.
要求符號和約定
1.2.
術語
2.
創建和更新會話
3.
會話狀態更改通知
3.1.
RP iframe
3.2.
OP iframe
3.3.
OpenID 提供方發現元數據
4.
驗證
5.
實施注意事項
5.1.
用戶代理阻止訪問第三方內容
6.
安全注意事項
7.
IANA 注意事項
7.1.用戶代理阻止對第三方內容的訪問
OAuth 參數注冊表
7.1.1.
注冊表內容
7.2.
OAuth 授權服務器元數據注冊表
7.2.1.
注冊內容
8.
參考文獻
8.1.
規范性參考文獻
8.2.
參考文獻
附錄 A.
致謝
附錄 B.
通知
§
作者地址
| 目錄 |
OpenID Connect 1.0 是 OAuth 2.0 [RFC6749](Hardt, D., Ed.,“OAuth 2.0 授權框架”,2012 年 10 月。)協議 之上的簡單身份層 。它使客戶端能夠根據授權服務器執行的身份驗證來驗證最終用戶的身份,并以可互操作和REST 風格的方式獲取有關最終用戶的基本資料信息。
該規范通過定義如何持續監控最終用戶在 OpenID 提供方處的登錄狀態來補充 OpenID Connect Core 1.0(Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“OpenID Connect Core 1.0”,2014 年 11 月。) [OpenID.Core] 規范,以便依賴方可以注銷已注銷的最終用戶。 OpenID 提供方。
此規范和 OpenID Connect 前端通道注?銷 1.0(Jones, M.,“OpenID Connect 前端注銷 1.0”,2022 年 9 月。) [OpenID.FrontChannel] 規范都使用前端通道注?通信,該通信通過用戶代理將注銷請求從 OP 傳送到 RP。相比之下, OpenID Connect 后端通道注?銷 1.0(Jones, M. 和 J. Bradley,“OpenID Connect 后端通道注?銷 1.0”,2022 年 9 月。) [OpenID.BackChannel] 規范使用 OP 和注銷的 RP 之間的直接后端通道注?通信。 OpenID Connect RP 發起的注銷 1.0(Jones, M.、de Medeiros, B.、Agarwal, N.、Sakimura, N. 和 J. Bradley,“OpenID Connect RP 發起的注銷 1.0”,2022 年 9 月。) [OpenID.RPInitiated] 規范通過定義依賴方請求 OpenID 提供方注銷最終用戶的機制來補充這些規范。該規范可以與其他三個規范單獨使用或結合使用。
| 目錄 |
本文檔中的關鍵詞“必須”、“不得”、“要求”、“應”、“不應”、“應該”、“不應該”、“推薦”、“不推薦”、“可以”和“可選”應按照RFC 2119(Bradner, S.,“RFC 中用于指示需求級別的關鍵詞”,1997 年 3 月。) [RFC2119] 中的描述進行解釋。
在本文檔的 .txt 版本中,引用值表示應按字面意思理解。在協議消息中使用這些值時,不得將引號用作值的一部分。在本文檔的 HTML 版本中,按字面意思取的值是通過使用這種固定寬度字體來指示的。
| 目錄 |
本規范使用OAuth 2.0(Hardt, D., Ed.,“OAuth 2.0 授權框架”,2012 年 10 月。) [RFC6749] 定義的術語“授權端點”、“授權服務器”、“客戶端”和“客戶端標識符”、RFC 7230(菲爾丁,R.,埃德。和 J. Reschke, Ed.,“超文本傳輸協議 (HTTP/1.1):消息語法和路由”,2014 年 6 月。) [RFC7230]定義的術語“用戶代理”以及定義的術語由 OpenID Connect Core 1.0(Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“OpenID Connect Core 1.0”,2014 年 11 月。) [OpenID.Core] 提供。
本規范還定義了以下術語:
- 會話
- 最終用戶依賴 OpenID 提供方執行的最終用戶身份驗證來訪問依賴方的連續時間段。
讀者重要提示:本節中的術語定義是本規范的規范部分,對實現提出了要求。本規范文本中的所有大寫單詞(例如“Session”)均引用這些定義的術語。每當讀者遇到它們時,都必須遵循本節中的定義。
| 目錄 |
在 OpenID Connect 中,RP 上的會話通常在 RP 驗證最終用戶的 ID 令牌時啟動。請參閱 OpenID Connect Core 1.0 [OpenID.Core](Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“OpenID Connect Core 1.0”,2014 年 11 月。) 規范,了解如何獲取 ID 令牌并驗證它。當OP支持會話管理時,它還必須返回會話狀態作為身份驗證響應中的附加session_state參數,并且還應該返回會話狀態作為身份驗證錯誤響應中的附加session_state參數。 OpenID Connect 身份驗證響應在 OpenID Connect Core 1.0 的第 3.1.2.5 節中指定。 OpenID Connect 身份驗證錯誤響應在 OpenID Connect Core 1.0 的第 3.1.2.6 節中指定。
這個參數是:
- 會話狀態
- 會話狀態。 JSON [RFC7159](Bray, T., Ed.,“JavaScript 對象表示法 (JSON) 數據交換格式”,2014 年 3 月。)字符串,表示最終用戶在 OP 的登錄狀態。它不得包含空格 (" ") 字符。該值對于 RP 來說是不透明的。如果支持會話管理,則這是必需。
會話狀態值最初是在服務器上計算的。用戶代理中的 OP iframe 也會重新計算相同的會話狀態值。合適的會話狀態值的生成在第 3.2 節(OP iframe)中指定,并且基于客戶端 ID、原始 URL 和 OP 用戶代理狀態的加鹽加密哈希。對于原始 URL,服務器可以使用身份驗證響應的原始 URL,遵循RFC 6454(Barth, A.,“Web 起源概念”,2011 年 12 月。) [RFC6454] 第 4 節中指定的算法。
| 目錄 |
非常希望能夠確定最終用戶在 OP 的登錄狀態。為此,可以使用 提示=無重復身份驗證請求。然而,這會導致網絡流量,并且這對于日益流行的移動設備來說是個問題。因此,一旦使用身份驗證請求和響應建立了會話,就希望能夠通過使用受源限制的 postMessage 從 RP iframe 輪詢隱藏的 OP iframe,來檢查 OP 的登錄狀態,而不會導致網絡流量,如下所示。
| 目錄 |
RP 從自身加載一個不可見的 iframe。這個 iframe 必須知道:
RP iframe 以適合 RP 應用程序的時間間隔使用 postMessage 輪詢 OP iframe。對于每個 postMessage,它發送第 3.2 節(OP iframe)中定義的會話狀態。 RP iframe 必須強制它只處理來自 OP 幀來源的消息。它必須拒絕來自任何其他來源的 postMessage 請求,以防止跨站點腳本攻擊。
來自 RP iframe 的 postMessage 傳遞以下串聯作為數據:
它還必須能夠接收從 OP iframe 返回的 postMessage。接收到的數據將被更改或 不變, 除非 OP 確定發送的消息的語法格式錯誤,在這種情況下,接收到的數據將是錯誤的。收到 changed后,RP必須執行 prompt=none的重新認證,以獲得OP的當前會話狀態。收到 錯誤后,RP 不得使用提示=無執行重新身份驗證,以免導致潛在的無限循環,從而生成到 OP 的網絡流量。
以下是 RP iframe 的非規范示例偽代碼:
var stat = "unchanged";
var mes = client_id + " " + session_state;
var targetOrigin = "https://server.example.com"; // Validates origin
var opFrameId = "op";
var timerID;
function check_session() {
var win = window.parent.frames[opFrameId].contentWindow
win.postMessage(mes, targetOrigin);
}
function setTimer() {
check_session();
timerID = setInterval(check_session, 5 * 1000);
}
window.addEventListener("message", receiveMessage, false);
function receiveMessage(e) {
if (e.origin !== targetOrigin) {
return;
}
stat = e.data;
if (stat === "changed") {
clearInterval(timerID);
// then take the actions below...
}
}
setTimer();
當 RP 檢測到會話狀態更改時,它應該首先嘗試在 iframe 內發出提示=無請求來獲取新的 ID 令牌和會話狀態,并將舊的 ID 令牌作為id_token_hint發送。如果 RP 收到同一最終用戶的 ID 令牌,它應該簡單地更新會話狀態的值。如果它沒有收到 ID 令牌或收到另一個最終用戶的 ID 令牌,則需要將這種情況作為原始最終用戶的注銷來處理。如果原始最終用戶已經在 RP 處注銷,而狀態變化表明最終用戶應該注銷,則認為注銷已成功。
請注意,會話狀態是原始綁定的。在多個子域共享同一 RP 會話的部署中,父窗口和 RP iframe 都設置相同的 document.domain以遵守同源限制非常重要。這將允許 RP iframe 定位父窗口的嵌入式 OP iframe。
| 目錄 |
RP 還會從 OP 的 check_session_iframe加載一個不可見的 OP iframe 到自身中。 RP 必須為 iframe 分配一個id屬性,以便它可以對其進行尋址,如上所述。 OP iframe 必須強制調用者來自預期的來源。它必須拒絕來自任何其他源的 postMessage 請求,以防止跨站點腳本攻擊。
如第 3.1 節(RP內嵌框架) 中所述,來自 RP iframe 的 postMessage 傳遞以下串聯作為數據:
OP iframe 可以訪問 OP 上的用戶代理狀態(在 cookie 或 HTML5 存儲中),它用于計算并與 RP 傳遞的 OP 會話狀態進行比較。 OP iframe 必須根據先前獲得的客戶端 ID、源原始 URL(來自 postMessage)和當前 OP 用戶代理狀態重新計算它。出于隱私原因,會話狀態包含所有這些信息,以便同一用戶代理中活動的不同客戶端具有不同的會話狀態值。
如果收到的 postMessage 語法錯誤,導致發布的客戶端 ID 和原始 URL 無法確定或語法無效,則 OP iframe 應該將字符串錯誤postMessage返回源。如果接收到的值和計算出的值不匹配,則 OP iframe 必須將更改后的字符串發送回源。如果匹配,那么它必須 postMessage 字符串 不變。
以下是 OP iframe 的非規范示例偽代碼:
window.addEventListener("message", receiveMessage, false);
function receiveMessage(e){ // e.data has client_id and session_state
var client_id = e.data.substr(0, e.data.lastIndexOf(' '));
var session_state = e.data.substr(e.data.lastIndexOf(' ') + 1);
var salt = session_state.split('.')[1];
// if message is syntactically invalid
// postMessage('error', e.origin) and return
// if message comes an unexpected origin
// postMessage('error', e.origin) and return
// get_op_user_agent_state() is an OP defined function
// that returns the User Agent's login status at the OP.
// How it is done is entirely up to the OP.
var opuas = get_op_user_agent_state();
// Here, the session_state is calculated in this particular way,
// but it is entirely up to the OP how to do it under the
// requirements defined in this specification.
var ss = CryptoJS.SHA256(client_id + ' ' + e.origin + ' ' +
opuas + ' ' + salt) + "." + salt;
var stat = '';
if (session_state === ss) {
stat = 'unchanged';
} else {
stat = 'changed';
}
e.source.postMessage(stat, e.origin);
};
OP 用戶代理狀態通常存儲在 cookie 或 HTML5 本地存儲中。它是與授權服務器綁定的源。它捕獲有意義的事件,例如登錄、注銷、用戶更改、最終用戶使用的客戶端的身份驗證狀態更改等。因此,OP 應更新用戶代理狀態的值以響應此類有意義的事件。因此,在此類事件發生后,下次調用 check_session() 將返回更改的值。建議 OP 在沒有有意義的事件的情況下不要過于頻繁地更新用戶代理狀態,以便在客戶端響應虛假更改事件時避免過多的網絡流量。
除了用戶代理狀態之外,響應不成功的身份驗證請求而返回的會話狀態的計算還應該以鹽的形式包含足夠的隨機性,以防止在連續調用 OP 的授權端點時識別最終用戶。
在授權客戶端(成功的身份驗證響應)的情況下,OP 應在以下事件之一下更改返回給客戶端的會話狀態值:
此外,用于驗證會話狀態的用戶代理狀態應該隨此類事件而改變。在此類事件發生后,對 check_session() 的調用將返回 針對早期版本的會話狀態的更改。建議在沒有此類事件的情況下,用戶代理狀態不應變化得太頻繁,以最大限度地減少客戶端對更改 通知的響應所引起的網絡流量。
如果身份驗證請求不成功導致身份驗證錯誤響應(如 OpenID Connect Core 1.0 第 3.1.2.6 節中指定),則返回的會話狀態值應隨每個請求而變化。但是,除非發生有意義的事件,否則用戶代理會話狀態不需要更改。特別地,會話狀態的許多值可以同時有效,例如通過在響應不成功的認證請求而發出的會話狀態中引入隨機鹽。
如果使用 cookie 來維護 OP 用戶代理狀態,則可能無法為此 cookie 設置 HttpOnly 標志,因為需要從 JavaScript 訪問它。因此,不應該將可用于識別用戶的信息放入cookie中,因為它可以被不相關的JavaScript讀取。
在一些實現中,僅當最終用戶的會話發生改變時才會發生改變的 通知,而在其他實現中,它們也可能由于用戶代理和OP之間的其他會話的改變而發生。 RP 需要為這兩種可能性做好準備,默默地處理可能發生的任何誤報。
| 目錄 |
為了支持OpenID Connect會話管理,RP需要獲取會話管理相關的OP元數據。此 OP 元數據通常通過 OP 的 Discovery 響應獲取,如OpenID Connect Discovery 1.0(Sakimura, N.、Bradley, J.、Jones, M. 和 E. Jay,“OpenID Connect Discovery 1.0”,2014 年 11 月。) [OpenID.Discovery] 中所述,或者可以通過其他機制獲知。
當支持會話管理和發現時,此 OpenID 提供方元數據參數必須包含在服務器的發現響應中:
- 檢查會話 iframe
- 必需。 OP iframe 的 URL,支持使用 HTML5 postMessage API 與 RP 客戶端進行會話狀態信息的跨源通信。該 URL 必須使用https方案,并且可以包含端口、路徑和查詢參數組件。該頁面是從嵌入在 RP 頁面中的不可見 iframe 加載的,以便它可以在 OP 的安全上下文中運行。它接受來自相關 RP iframe 的 postMessage 請求,并使用 postMessage 回發最終用戶在 OP 的登錄狀態。
| 目錄 |
如果本規范中定義的任何驗證過程失敗,則必須中止任何需要未能正確驗證的信息的操作,并且不得使用未能正確驗證的信息。
| 目錄 |
該規范定義了依賴方和選擇實施會話管理的 OpenID 提供方所使用的功能。所有這些依賴方和 OpenID 提供方必須實現本規范中列出的“必需”或“必須”描述的功能。
| 目錄 |
請注意,在撰寫本文時,一些用戶代理(瀏覽器)開始默認阻止對第三方內容的訪問,以阻止用于跟蹤最終用戶跨網站活動的某些機制。具體而言,被阻止的第三方內容是來源與焦點用戶代理窗口來源不同的網站內容。網站數據包括 Cookie 和任何 Web 存儲 API(sessionStorage、localStorage 等)。
這可以防止來自 RP 處的 OP 的通知能夠訪問 RP 的用戶代理狀態以實施本地注銷操作。特別是,cookie 和 Web 存儲 API 在 RP 上下文中加載的 OP 框架中可能不可用。這里的副作用是,根據所使用的機制(cookie 或 Web 存儲),重新計算session_state所需的數據可能不可用。基于 Cookie 的實現可能會為每次調用返回更改,從而導致重新身份驗證的無限循環。因此,建議此規范的部署包含防御代碼來檢測這種情況,并在可能的情況下通知最終用戶無法執行請求的 RP 注銷。所需防御代碼的詳細信息超出了本規范的范圍;它可能因用戶代理而異,并且可能隨著時間的推移而變化,因為用戶代理跟蹤預防情況是不穩定的并且不斷發展。
(Jones, M. 和 J. Bradley,“OpenID Connect 后端通道注?銷 1.0”,2022 年 9 月。)目前尚不清楚 OpenID Connect Back-Channel Logout 1.0 [OpenID.BackChannel] 是否會受到這些開發的影響。
| 目錄 |
OP iframe 必須強制調用者來自預期的來源。它必須拒絕來自任何其他源的 postMessage 請求,以防止跨站點腳本攻擊。
RP iframe 必須強制它只處理來自 OP 幀來源的消息。它必須拒絕來自任何其他源的 postMessage 請求,以防止跨站點腳本攻擊。
| 目錄 |
| 目錄 |
本規范在RFC 6749 [RFC6749] 建立的 IANA“OAuth 參數”注冊表[IANA.OAuth.Parameters](IANA,“OAuth 參數” 。)中注冊以下參數。 (Hardt, D., Ed.,“OAuth 2.0 授權框架”,2012 年 10 月。)
| 目錄 |
| 目錄 |
本規范在[RFC8414] 建立的 IANA“OAuth 授權服務器元數據”注冊表[IANA.OAuth.Parameters](IANA,“OAuth 參數” 。)中注冊以下元數據名稱。 (Jones, M.、Sakimura, N. 和 J. Bradley,“OAuth 2.0 授權服務器元數據”,2018 年 6 月。)
| 目錄 |
| 目錄 |
| 目錄 |
| [IANA.OAuth.參數] | IANA,“ OAuth 參數”。 |
| [OpenID.BackChannel] | Jones, M. 和 J. Bradley,“ OpenID Connect 后端通道注?銷 1.0 ”,2022 年 9 月。 |
| [OpenID.核心] | Sakimura, N.、Bradley, J.、Jones, M.、de Medeiros, B. 和 C. Mortimore,“ OpenID Connect Core 1.0 ”,2014 年 11 月。 |
| [OpenID.發現] | Sakimura, N.、Bradley, J.、Jones, M. 和 E. Jay,“ OpenID Connect Discovery 1.0 ”,2014 年 11 月。 |
| [OpenID.FrontChannel] | Jones, M.,“ OpenID Connect 前端注銷 1.0 ”,2022 年 9 月。 |
| [OpenID.RP發起] | Jones, M.、de Medeiros, B.、Agarwal, N.、Sakimura, N. 和 J. Bradley,“ OpenID Connect RP 發起的注銷 1.0 ”,2022 年 9 月。 |
| [RFC2119] | Bradner, S.,“ RFC 中用于指示需求級別的關鍵字”,BCP 14,RFC 2119,DOI 10.17487/RFC2119,1997 年 3 月。 |
| [RFC6454] | Barth, A.,“ Web 起源概念”,RFC 6454,DOI 10.17487/RFC6454,2011 年 12 月。 |
| [RFC6749] | Hardt, D., Ed.,“ OAuth 2.0 授權框架”,RFC 6749,DOI 10.17487/RFC6749,2012 年 10 月。 |
| [RFC7159] | Bray, T., Ed.,“ JavaScript 對象表示法 (JSON) 數據交換格式”,RFC 7159,DOI 10.17487/RFC7159,2014 年 3 月。 |
| [RFC7230] | 菲爾丁,R.,埃德。和 J. Reschke, Ed.,“超文本傳輸協議 (HTTP/1.1):消息語法和路由”,RFC 7230,DOI 10.17487/RFC7230,2014 年 6 月。 |
| 目錄 |
| [RFC8414] | Jones, M.、Sakimura, N. 和 J. Bradley,“ OAuth 2.0 授權服務器元數據”,RFC 8414,DOI 10.17487/RFC8414,2018 年 6 月。 |
| 目錄 |
OpenID 社區感謝以下人員對此規范做出的貢獻:
納文·阿加瓦爾 (Naveen.Agarwal@microsoft.com),微軟
阿曼達·安加內斯 (aanganes@mitre.org),MITRE
約翰·布拉德利 (ve7jtb@ve7jtb.com),尤比科
布雷諾·德·梅代羅斯 (breno@google.com),Google
弗拉基米爾·朱維諾夫 (vladimir@connect2id.com),Connect2id
喬治·弗萊徹 (gffletch@aol.com),第一資本
埃德蒙·杰伊 (ejay@mgi1.com),伊魯米拉
邁克爾·B·瓊斯 (mbj@microsoft.com),微軟
湯姆·瓊斯 (thomasclinganjones@gmail.com),獨立人士
托德·萊恩哈特 (lainhart@us.ibm.com),IBM
托斯頓·洛德斯泰特 (torsten@lodderstedt.net),yes.com
安東尼·納達林 (nadalin@prodigy.net),獨立
Axel Nennker (axel.nennker@telekom.de),德國電信
Justin Richer (justin@bspk.io),定制工程
Nat Sakimura (nat@nat.consulting),NAT.Consulting
菲利普·斯科坎 (panva.ip@gmail.com),Auth0
漢斯·贊德貝爾特 (hans.zandbelt@zmartzone.eu),ZmartZone
| 目錄 |
版權所有 (c) 2022 OpenID 基金會。
OpenID 基金會 (OIDF) 向任何貢獻者、開發者、實施者或其他相關方授予非排他性、免版稅、全球版權許可,以復制、分發、執行和展示本實施者草案或最終規范、準備衍生作品、分發、執行和展示僅用于 (i) 制定規范,以及 (ii) 根據此類文件實施實施者草案和最終規范,前提是注明材料來源為 OIDF,但此類來源并不表示認可由 OIDF 制定。
本規范中描述的技術來自各種來源的貢獻,包括 OpenID 基金會的成員和其他人。盡管 OpenID 基金會已采取措施幫助確保該技術可供分發,但它對可能聲稱與實施或使用該技術相關的任何知識產權或其他權利的有效性或范圍不持任何立場。本規范或此類權利下的任何許可可能或可能不可用的范圍;它也不代表它已做出任何獨立努力來確定任何此類權利。 OpenID 基金會和本規范的貢獻者不做出(并特此明確否認任何)與本規范相關的保證(明示、暗示或其他方式),包括適銷性、不侵權、特定用途的適用性或所有權的暗示保證。規范,并且實施該規范的全部風險由實施者承擔。 OpenID 知識產權政策要求貢獻者提供專利承諾,不會針對其他貢獻者和實施者提出某些專利主張。 OpenID 基金會邀請任何感興趣的各方提請其注意可能涵蓋實踐本規范所需的技術的任何版權、專利、專利申請或其他專有權利。
| 目錄 |
| 布雷諾·德·梅代羅斯 | |
| 谷歌 | |
| 電子郵件: | breno@google.com |
| 納文·阿加瓦爾 | |
| 微軟 | |
| 電子郵件: | 納文.Agarwal@microsoft.com |
| 納特·薩基穆拉 | |
| NAT咨詢 | |
| 電子郵件: | nat@nat.consulting |
| 約翰·布拉德利 | |
| 尤比科 | |
| 電子郵件: | ve7jtb@ve7jtb.com |
| 邁克爾·瓊斯 | |
| 微軟 | |
| 電子郵件: | mbj@microsoft.com |