OIDC / OAuth2.0 是一種開放的标準,可以幫助應用程式安全地通路使用者的資源,而無需将使用者的憑據(如使用者名和密碼)暴露給應用程式,我們可以通過标準協定,建立集中的使用者目錄和統一認證中心,将内外部業務系統的登入認證統一到認證中心,實作集中化的管理,進而避免每套業務系統都要搭建一套使用者體系所造成的管理側不便及安全側的風險。
本文将帶各位詳細了解 OAuth 2.0 & OIDC 及其授權模式。
01 協定介紹
1.1 OAuth 2.0 & OIDC
OAuth 2.0 是一個授權架構,使應用程式能夠獲得對 HTTP 服務上使用者帳戶的有限通路權限,例如 Facebook、GitHub 和 DigitalOcean。它通過将使用者認證委托給托管使用者帳戶的服務,并授權第三方應用程式通路使用者帳戶來實作。
OpenID Connect (OIDC) 是建立在 OAuth 2.0 架構之上的簡單身份層。它在 OAuth 2.0 提供的授權的基礎上添加了認證。
初看上面這段話你可能很難了解,這裡用白話解釋下,OAuth 2.0 在設計之初,是為了 API 安全的問題,它是一個授權協定,而 OIDC 則在 OAuth2.0 協定的基礎上,提供了使用者認證、擷取使用者資訊等的标準實作,當然我們也可以了解擷取使用者資訊也是一個 API ,用 OAuth 2.0 也沒問題的,考慮到讀者的感受,在這裡不要過于糾結,隻要記住 OIDC 是完全相容 OAuth2.0 的,我們現在也推薦用 OIDC。
1.2 術語介紹
啥啥啥,寫的這都是啥,小白看到這些腦袋都大了,我在這裡重點說下 OIDC/OAuth2.0 協定互動時所參與的幾個角色,等你對協定熟悉了,可以反過頭來再看下相關的介紹,在接下來的授權模式介紹中,我們會結合這四個角色,介紹下不同授權模式的流程。
- 資源持有者(End User / Resource Owner) 終端使用者
- 應用/用戶端(Client)應用的前端,可以是 web 端、App 端、移動端應用
- 資源伺服器(Resource Server) Client 對應的背景
- 認證伺服器(OpenID Provider / Auhtorization Server)即 Authing
1.3 Client 類型介紹
OAuth2.0 / OIDC 中定義了 2 種 Client 類型:
我們在這裡解釋下:
Confidential Clients 機密型應用:能夠安全的存儲憑證(client_secret),例如有後端服務,你的前端是 Vue,背景是 Java ,那麼可以了解為機密性應用,因為你的後端能夠安全的儲存 client_secret,而不會将 client_secret 直接暴露給使用者,此時你可以使用授權碼模式。
Public Clients 公共型應用:無法安全存儲憑證(Client Secrets),例如 SPA 、移動端、或者完全前後端分離的應用,應當使用授權碼 + PKCE 模式
1.4 OIDC 授權模式與選型建議
重點來啦!我們要了解授權模式,才能更好的針對系統類型進行授權模式的選型,避免由于授權模式選型不當所造成的開發工作增加和安全側的漏洞。
- 授權模式
- 選型建議
02 授權模式詳細介紹
2.1 授權碼模式(Authorization Code)
授權碼模式适合應用具備後端伺服器的場景。授權碼模式要求應用必須能夠安全存儲密鑰,用于後續使用授權碼換 Access Token。授權碼模式需要通過浏覽器與終端使用者互動完成認證授權,然後通過浏覽器重定向将授權碼發送到後端服務,之後進行授權碼換 Token 以及 Token 換使用者資訊。
整體上,有以下流程:
- 在你的應用中,讓使用者通路登入連結,浏覽器跳轉到 Authing,使用者在 Authing 完成認證。
- 浏覽器接收到一個從 Authing 伺服器發來的授權碼。
- 浏覽器通過重定向将授權碼發送到你的應用後端。
- 你的應用服務将授權碼發送到 Authing 擷取 AccessToken 和 IdToken,如果需要,還會傳回 refresh token。
- 你的應用後端現在知道了使用者的身份,後續可以儲存使用者資訊,重定向到前端其他頁面,使用 AccessToken 調用資源方的其他 API 等等。
流程圖如下:
2.2 授權碼 + PKCE 模式(Authorization Code With PKCE)
如果你的應用是一個 SPA 前端應用或移動端 App,建議使用授權碼 + PKCE 模式來完成使用者的認證和授權。授權碼 + PKCE 模式适合不能安全存儲密鑰的場景(例如前端浏覽器) 。
我們解釋下 code_verifier 和 code_challenge。
code_verifier:在 [A-Z] / [a-z] / [0-9] / "-" / "." / "_" / "~" 範圍内,生成43-128位的随機字元串。
code_challenge:則是對 code_verifier 通過 code_challenge_method 例如 sha256 轉換得來的。
用大白話講下就是在認證是使用者攜帶的是加密後的 code_challenge ,在使用者認證成功擷取 Token 時,用戶端證明自己的方式則是把 code_verifier 原文發送,認證中心收到擷取 Token 請求時通過 code_verifier + code_challenge_method 進行轉換,發現最終結果與 code_challenge 比對則傳回 Token ,否則拒絕。
整體上,有以下流程:
- 在你的應用中,讓使用者通路登入連結(包含 code_challenge ) ,浏覽器跳轉到 Authing,使用者在 Authing 完成認證。
- 浏覽器接收到一個從 Authing 伺服器發來的授權碼。
- 浏覽器通過重定向将授權碼發送到你的應用前端。
- 你的應用将授權碼和 code_verifier 發送到 Authing 擷取 AccessToken 和 IdToken,如果需要,還會傳回 Refresh token。
- 你的應用前端現在知道了使用者的身份,後續使用 Access token 換取使用者資訊,重定向到前端其他頁面,使用 AccessToken 調用資源方的其他 API 等等。
流程圖如下:
2.3 用戶端憑證模式(Client Credentials)
Client Credentials 模式用于進行伺服器對伺服器間的授權(M2M 授權),期間沒有使用者的參與。你需要建立程式設計通路賬号,并将 AK、SK 密鑰對交給你的資源調用方。
注意:Client Credentials 模式不支援 Refresh Token。
整體上,有以下流程:
- 資源調用方将他的憑證 AK、SK 以及需要請求的權限 scope 發送到 Authing 授權端點。
- 如果憑證正确,并且調用方具備資源權限,Authing 為其頒發 AccessToken。
流程圖如下:
2.4 隐式模式(Implicit)(不推薦)
隐式模式适合不能安全存儲密鑰的場景(例如前端浏覽器),不推薦此模式,建議采用其他模式。在隐式模式中,應用不需要使用 code 換 token,無需請求 /token 端點,AccessToken 和 IdToken 會直接從認證端點傳回。
注意:因為隐式模式用于不能安全存儲密鑰的場景,是以隐式模式不支援擷取 Refresh Token。
整體上,有以下流程:
- 在你的應用中,讓使用者通路登入連結,浏覽器跳轉到 Authing,使用者在 Authing 完成認證。
- Authing 将浏覽器重定向到你的應用回調位址,AccessToken 和 IdToken 作為 URL hash 傳遞。
- 你的應用從 URL 中取出 token。
- 你的應用可以将 AccessToken 與 IdToken 儲存,以便後續使用,例如攜帶 AccessToken 通路資源伺服器,攜帶 IdToken 請求服務端進而服務端能夠辨識使用者身份。
流程圖如下:
2.5 密碼模式(Password)(不推薦)
不推薦使用此模式,盡量使用其他模式。隻有其他模式都無法解決問題時才會考慮使用密碼模式。如果使用密碼模式,請確定你的應用代碼邏輯非常安全,不會被黑客攻擊,否則将會直接洩露使用者的賬密。一般用于改造內建非常古老的應用,否則絕對不要把它作為你的第一選擇。
整體上,有以下流程:
- 你的應用讓使用者輸入賬密資訊。
- 你的應用将使用者賬密發送到 Authing 。
- 如果賬密正确,Authing 傳回 token 。
流程圖如下:
2.6 裝置代碼模式(Device Code)(幾乎用不到)
對于一些連接配接到網際網路的輸入受限裝置,裝置不會直接驗證使用者身份,而是讓使用者通過連結或二維碼轉到手機或電腦上進行認證,進而避免了使用者無法輕松輸入文本所帶來的糟糕體驗。
Device Code Flow這個與前面幾個不太一樣,開始不再是由資源持有者發起,而是由用戶端開始。甚至登入的方法與用戶端還沒有特别的關聯。
大緻流程說明如下:
- 用戶端發起向認證伺服器取得 device_code 和user_code 。
- 用戶端通過二維碼或者其他方式将 user_code交給資源持有者。
- 資源持有者透過某個端點 (endpoint) 與user_code 進行認證。
- 用戶端通過 device_code 輪訓認證伺服器是否有人認證,若有人認證則會傳回 access_token 。
流程圖如下:
一個設計良好的系統,都需要一個标準、安全、可擴充的使用者認證協定,無論是 ToC 還是 ToE ,接來下我們還會針對具體的授權模式結合實際場景講一下具體的模式。
本章總結
- 本章我們介紹了 OIDC 和 OAuth2.0 兩個協定,在使用起來,這兩個協定并沒有太大的差別,OAuth2.0 是一個授權協定,OIDC 協定則是在 OAuth2.0 的提供的授權的基礎上添加了認證。
- 授權模式,我們分别介紹了授權碼模式(Authorization Code) 、授權碼 + PKCE 模式(Authorization Code With PKCE) 、用戶端憑證模式(Client Credentials) 、隐式模式(Implicit)(不推薦)、密碼模式(Password) (不推薦)、裝置代碼模式(Device Code)(幾乎用不到) 。
- 授權模式選擇
- 如果我們的應用是 WEB 端應用,那我們應該選擇授權碼模式(Authorization Code)
- 如果我們是原生應用,例如 SPA ,移動端,那我們應該選擇授權碼 + PKCE 模式(Authorization Code With PKCE)
- 如果我們是想把應用的 API 給第三方服務安全的調用,則需要選擇用戶端憑證模式(Client Credentials)
接下來我們還會詳細介紹授權碼模式(Authorization Code)、授權碼 + PKCE 模式(Authorization Code With PKCE)、用戶端憑證模式(Client Credentials)如何接入 Authing。敬請期待!
推薦閱讀:
如何使用 Authing 實作 AWS CLI 單點登入?
Authing 結合 APISIX 實作統一可配置 API 權限網關(快速啟動版)
如何增強企業數字靈活性?|身份雲研究院
點選右側「連結」,立刻了解 Authing !