keycloak
Tool
在這部分,我們將探討OIDC和SAML。正如前一章節所提,身分驗證和授權是整個安全流程中非常關鍵的環節。一般來說,會有專門的解決方案來處理這些問題。OIDC和SAML都是為這個目的而設計的標準協議,它們提供一個集中式的方法來驗證使用者身份,並界定他們可以訪問哪些資源或執行哪些操作。
OIDC是一個建立在OAuth 2.0之上的身分認證層。OAuth 2.0本身是一個專注於授權的框架,而OIDC則在這個基礎上增加了身分驗證功能。這樣,應用程式不僅能知道使用者有哪些權限,還能瞭解使用者是誰,並獲取他們的基本資訊,比如名稱和電子郵件地址。
OAuth 2.0 是一個授權框架,允許第三方應用程式在使用者同意的情況下存取使用者在某個服務上的資訊,而不需要分享使用者的密碼。通常在OAuth 2.0,會有幾個角色,我們這邊舉一個簡單情境,你希望使用「快速日記」App,而這個App提供使用Google帳戶登入的功能來使用Google雲端硬碟服務。
Resource Owner(資源擁有者) : 通常就是User(你), 能授予應用程式取得受保護資料的人,通常就是終端使用者(end-user)。例如你希望使用「快速日記」App,而這個App提供使用Google帳戶登入的功能。在OAuth的流程中,當App請求許可存取你的資料時,你會給予(或拒絕)這個請求。
Resource Server(Resource Server) : 存放使用者受保護資料的伺服器,以這個例子來說就是Google雲端硬碟,當「快速日記」App希望保存或讀取日記時,它會向此伺服器提出請求。
Client (客戶端):通常指稱想要取得受保護資源的「應用程式」,以這個例子來說就是「快速日記」App。 當「快速日記」App希望保存或讀取日記時,它會向此伺服器提出請求。
Authorization Server (授權伺服器) : 驗證 Resource Owner 的身份,並且在獲得同意之後,發放「Access Token」給應用程式(Client)的伺服器。以這個例子來說就是 (Google的授權伺服器)。
下圖整個驗證Flow
Request Credentials : 當你打開「快速日記」App並選擇使用Google帳戶登入時,App首先會引導你到Google的登入頁面。
Authenticate : 你將在Google的頁面上輸入你的Google帳戶憑證,即用戶名和密碼。這一步是由Google完成的,而「快速日記」App不會看到或知道你的密碼。
Consent : 一旦驗證成功,Google會顯示一個請求同意頁面。在這裡,Google會詢問你是否允許「快速日記」App訪問特定的Google帳戶資料。
Credentials : 「Resource Owner」(使用者)提供的身份資訊或某種用於辨識其身份的資料。這只是一個授權請求,而實際的身份驗證會在Resource Owner和Authorization Server之間完成。
Authorization Request : 如果你同意上述的權限請求,「快速日記」App會從Google的授權伺服器請求一個授權碼。
Authorization Code : Google的授權伺服器會回傳一個短暫的授權碼給「快速日記」App。
Access Token : ,「快速日記」App會使用這個授權碼再次向Google的授權伺服器請求取得訪問令牌(Access Token)。
Access Token: 一旦取得訪問令牌,「快速日記」App便可以使用此令牌來存取Google雲端硬碟(或其他你同意的資料)。
Protected Resource: 當「快速日記」App希望保存或讀取日記時,它會使用這個Access Token向Google雲端硬碟(作為資源伺服器)提出請求,然後Google雲端硬碟會根據該令牌提供相對應的資料或服務。
更詳細的其實還有關係到Redirect部分,可以參照這篇 https://cloudsundial.com/salesforce-oauth-flows 寫得還算詳細。
如果覺得這範例太複雜,以下是一個更簡單的流程圖(LEO提供)
上面的介紹讓我們對 OAuth 2.0 有了清晰的認識,OAuth 2.0 主要是設計來授予第三方應用程式存取特定資源的權限,而不需要分享密碼。它的核心目標是安全地授權,但它本身並不提供一個方式來傳送使用者的身份資訊。換句話說,OAuth 2.0 主要關心的是「授權」,而不是「認證」。
那麼,回到 OpenID Connect(OIDC)。它在 OAuth 2.0 的基礎上添加了一層「身份認證」的功能。這使得授權伺服器也能扮演身份提供者(Identity Provider,IDP)的角色,並提供關於使用者身份的資訊。
舉上述例子,當你使用 Google 帳戶登入「快速日記」App,這個 App 不僅獲得了存取你 Google 雲端硬碟的權限(這部分是 OAuth 2.0 負責的),還知道了你的基本身份資訊,比如名字和電子郵件(這部分就是 OIDC 負責的)。
總結一下,OAuth 2.0 負責「授權」,讓應用程式有權限執行某些操作,而 OIDC 則確定「你是誰」,提供身份認證。兩者合作,就形成了一個完整的身份驗證和授權解決方案。需要注意的是,身份認證還有其他方式,比如使用 JWT Token。
OAuth 2.0是一個授權的實作概念,IDP則是認證的實作概念
所以從我們上述OAuth2.0的圖看,授權伺服器(Authorization Server) 不僅會回傳一個「存取令牌(Access Token)」,還會附帶一些關於使用者的身份資訊。
下面有一張圖很簡單暴力,可以看到Open ID跟OAuth驗證,關鍵在回傳Authorization資料會更完整的包含身分訊息。
註:IDP只提供身分識別與認證,不包含授權喔!
OICD資料由JSON格式來儲存類似的信息,在OIDC中這種JSON對象通常被稱為ID Token。內如基本上如下
範例
SAML,全名是"Security Assertion Markup Language",主要是用於在身份提供者(Identity Provider,簡稱IdP)和服務提供者(Service Provider,簡稱SP)之間交換認證和授權資訊的一種網路標準。但他不僅支持身份驗證,也支持豐富的授權功能。另外SAML主要焦點更傾向於身份驗證和單一登入(SSO)。通常使用HTTP POST方法來傳遞斷言(Assertion),與OIDC使用多種方法來傳遞ID令牌(ID Token),包括HTTP Header和URL參數會有點不太一樣。
這個標準包含三個主要角色:
Identity Provider(身分提供者) : 這個是專門負責驗證你是誰的系統。以上述例子Google來看,它就是一個IdP。
Service Provider(服務提供者) : 這些是你想要使用的各種線上服務,比如說郵件系統或報銷系統。
Agent(代理) : 這是參與認證和授權過程的軟件,通常是你的瀏覽器或其他類型的客戶端應用。
當你試著使用某個服務(SP)時,這個服務會先引導你到身份提供者(IdP)進行身份驗證。成功認證後,IdP會回傳一個證明給SP,證明你確實是誰。SP收到這份證明後,就會授予你訪問它所提供的服務的權限。
細部流程如下,
以我們OAuth2.0的「快速日記」App為例子,Service Provider (SP)為「快速日記」App,Identity Provider (IdP)為Google,User Agent就是你所使用的裝置(例如手機、電腦等)上的瀏覽器或「快速日記」App應用程式。另外,Google雲端硬碟(Google Drive)部分也會算是 Service Provider這一區塊。
最後這邊稍微提一下,流程有一個步驟是回傳XHTML,在SSO(單一登入)的流程中,當身份提供者(Identity Provider)需要讓使用者完成某些操作,例如輸入帳號密碼或選擇身份認證方式時,它會傳回一個XHTML頁面給User Agent(通常是瀏覽器)來顯示。舉個例子,想像你嘗試使用Google帳戶登入一個App。當你點擊"使用Google登入"後,如果你尚未在Google登入或Google需要確認你的身份,你的瀏覽器會被重導向至Google的登入頁面。這個登入頁面就是一個由Google傳回的XHTML內容。
簡單來說,XHTML的回傳就是在說:「這裡有一個網頁內容,請瀏覽器將其顯示給使用者。」在你提到的流程中,當身份提供者回傳XHTML給User Agent,就是讓瀏覽器展示某些內容或請求使用者完成某些操作,如登入或選擇認證方式。
SAML中,數據通常會以一個XML文件的形式出現,這個文件被稱為「斷言」(Assertion)。斷言中會包含多種元素,例如:
範例
最後比較整理一下這兩者不同
在我們討論OIDC(OpenID Connect)和SAML(安全斷言標記語言)的過程中,Identity Provider(IDP)扮演著關鍵角色。IDP負責驗證使用者身份,存儲和管理使用者的認證資料,如用戶名和密碼。一旦使用者成功通過認證,IDP會生成一份斷言(例如,SAML斷言)。這份斷言不僅包括使用者的基本身份資訊,還可能包含其他特定屬性。由於這份斷言是加密和簽名的,服務提供者(Service Provider, SP)可以驗證其真實性。透過IDP,使用者可以單一登入(SSO)以訪問多個相關服務或應用程式。
讓我們簡單看一下IDP如何進行身份管理:
於斷言或令牌中,一般會包含以下幾項信息:
例如,當使用Keycloak作為IDP時,它會發行一個格式為JWT(JSON Web Token)的令牌作為身份證明。