iT邦幫忙

2024 iThome 鐵人賽

DAY 23
2
Software Development

微服務奇兵:30天Quarkus特訓營系列 第 23

開發觀念建置-關於身分識別授權流程

  • 分享至 

  • xImage
  •  

本來想繼續寫關於微服務的內容,但今天比較忙,只好分享之前整理的筆記來當作今天的主題。在使用公有雲時,理解身份認證、OAuth 2.0、SAML和OpenID Connect等技術是非常重要的,因為這些技術提供了安全且標準化的方式來管理應用程式的用戶身份驗證。作為自動化背景出身的我,對這方面的知識相對薄弱,不過在後來處理大型雲端專案時,漸漸發現這些技術是不可避免的。因此,我花了一些時間學習並記錄這些觀念,分享給大家。

關於身份驗證與授權

當我們在設計系統時,清楚了解誰在使用系統以及這位使用者擁有什麼權限是很重要的環節。步驟分成身份驗證和授權。身份驗證確保系統知道使用者是誰,而授權則賦予他們可以執行的特定操作。整個過程可以被分解為四個部分:

  • 身分識別 (Identification):身分識別是讓系統知道你是誰的第一步。當你輸入用戶名、電子郵件地址等信息登入系統時,這個過程就是在進行身分識別。它是一種初步的識別,尚未驗證你是否擁有這個身份。

    EX : 輸入基本資料,例如用戶名和密碼

  • 身分驗證 (Authentication):系統確認你的身份是否合法的過程。通常會要求你提供密碼、指紋、FaceID或雙因素認證(2FA)等識別方式,來證明你的身份。

EX: 密碼驗證、二次驗證,例如OTP、FaceID,或是手機&Mail驗證

  • 授權 (Authorization):身分驗證通過後,系統會根據使用者的角色賦予不同的權限。授權控制的是"使用者可以做什麼",也就是說系統會根據你所屬的角色來限制或開放功能。例如,一個編輯者角色可能擁有編輯、創建和刪除內容的權限,而閱讀者則只能瀏覽信息。這個過程通過角色分配和權限管理來實現。

    EX : 角色分配(RBAC)

  • 存取控制 (Access Control):存取控制進一步落實授權細節,決定具體的資源或功能該如何進行限制。例如,在一個IT管理系統中,普通使用者可能只能查看伺服器日誌,但無法部署新應用程式;而系統管理員則擁有廣泛的操作權限。這些細緻的權限設置有助於防止誤操作或惡意攻擊,保護關鍵資源。

    EX: 角色檢查,API Scope應用

在使用者登入系統時,整個流程通常是先完成身分識別身分驗證,系統確認身份後,再根據身份賦予相應的授權。至於具體的權限設定,通常在系統後台可以針對不同角色進行靈活配置,例如基於RBAC(角色基礎存取控制)模型。

OAuth 2.0、Security Assertion Markup Language( SAML)和OpenID Connect(OIDC)

了解系統中對於身份識別授權對於資源的訪問前後關係後,接著來談最常見的授權框架(標準規範)OAuth2.0、與 認證協定 OpenID Connect。它們來自IETF(Internet Engineering Task Force)所訂的規範,RFC 6749。OAuth 2.0為一個標準的授權框架,而OIDC是在 OAuth 2.0 之上構建,專門用於身份驗證的協議。SAML則是OASIS(Organization for the Advancement of Structured Information Standards)所制定,主要應用於企業級的身份管理系統,在早期的企業級系統是很常見的認證協定所使用的Solution。接著來對每一項做一個了解。

OAuth 2.0

OAuth 2.0 為IETF所制定的開放標準授權框架,允許第三方應用程序以有限的訪問權限來請求資源所有者的資源,而不需要暴露用戶的憑證(如密碼)。簡單來說,它設計用意在於使應用程序能夠以一個受限的方式訪問用戶的資源,而不需要用戶提供他們的密碼給這些應用程序。在框架中,會有幾種角色設定如下

  • 資源所有者(Resource Owner):通常是用戶,擁有特定的資源(例如照片、數據等)。
  • 客戶端(Client):第三方應用程序,請求資源所有者授權以便訪問索取資源。
  • 授權伺服器(Authorization Server):負責驗證資源所有者的身份並授權授權碼或訪問令牌(Access Token)給客戶端。
  • 資源伺服器(Resource Server):存儲資源,並在收到有效的訪問令牌時向客戶端提供受保護的資源。

它的具體流程如下(來自**RFC 6749)**
https://ithelp.ithome.com.tw/upload/images/20240924/20115895y3J5ROfAnG.png

(A) Authorization Request(授權請求): 客戶端向資源所有者(如用戶)請求授權,通常會Redirect到授權伺服器上的一個網頁進行的。

(B) Authorization Grant(授權憑證): 資源所有者同意授權後,授權伺服器會頒發一個授權碼或其他形式的授權憑證給客戶端。

(C) Authorization Grant -> Authorization Server(授權憑證提交): 客戶端將授權碼(或授權憑證)提交給授權伺服器以換取訪問令牌(Access Token)。

(D) Access Token(訪問令牌):授權伺服器驗證授權憑證後,向客戶端發送訪問令牌(Access Token)。

(E) Access Token -> Resource Server(使用訪問令牌請求資源):客戶端使用該訪問令牌向資源伺服器請求資源。

(F) Protected Resource(保護資源):資源伺服器驗證訪問令牌,並在有效的情況下返回所請求的受保護資源。「有效」通常包括以下幾個方面:Token沒過期、Token沒被撤銷、Token權限正確…

這邊給一個具體情境,假設你正在使用一個理財App,它可以幫你自動從銀行帳戶中抓取每個月的消費紀錄,然後整理成報表,幫助你分析每月的開支情況。角色如下

  • 資源所有者(Resource Owner): 資源所有者就是。你擁有與銀行帳戶相關的資料,例如每月的消費紀錄。你有權決定是否允許其他應用程式(例如理財App)存取這些資料。
  • 客戶端(Client): 理財App就是客戶端。它希望透過你的認可來存取你的消費紀錄,從而幫助你分析財務狀況。理財App需要得到你的授權,才能合法地存取你的資料。
  • 授權伺服器(Authorization Server): 銀行的授權系統就是授權伺服器。
  • 資源伺服器(Resource Server):銀行的資料伺服器就是資源伺服器,負責存放你帳戶的消費紀錄等敏感資料。

以此範例整個OAuth2.0流程如下

Step1:授權請求(Authorization Request):當你第一次使用這個理財App,它會告訴你需要存取你的銀行消費紀錄。接著,它會跳轉到銀行的授權頁面。

Step2:授權頁面(Authorization Page):在這個頁面上,你會看到銀行列出理財App想要存取的資料範圍(例如每月消費紀錄),然後你可以選擇同意或拒絕(也有可能是輸入帳密,但是針對銀行系統去輸入帳密,不是App本身)。如果你同意,銀行就會生成一個授權碼。

Step3:授權碼交換令牌(Authorization Code Exchange for Token):理財App會帶這個授權碼去銀行的授權伺服器(Authorization Server)兌換訪問令牌(Access Token)。這個令牌類似一個通行證,可以讓App短時間內存取你的資料,但App本身並不知道你的銀行密碼。

Step4:取得消費紀錄(Access Protected Resources):理財App帶這個訪問令牌,向銀行的資源伺服器(Resource Server)請求每月的消費紀錄。銀行伺服器會檢查訪問令牌是否有效(例如令牌是否過期、是否有正確的權限),如果有效,就把消費紀錄發送回理財App。

從這個範例就可以感受到OAuth2.0的優點有

  • 安全:理財App無法直接存取你的帳戶密碼,這降低了敏感資訊被洩露的風險。
  • 控制權:你可以隨時在銀行的設定裡撤銷這個App的存取權限,訪問令牌就會失效。
  • 自動更新:理財App在你授權後,可以在訪問令牌有效期內自動取得最新的銀行資料,而不需要你每次重新登入或手動操作。

OpenID Connect(OIDC)

上面的介紹讓我們對 OAuth 2.0 有了清晰的認識,OAuth 2.0 主要是設計來授予第三方應用程式存取特定資源的權限,而不需要分享密碼。OAuth 2.0 的核心目標是安全地授權,但它本身並不包含傳遞使用者身份資訊的機制。換句話說,OAuth 2.0 主要關心的是「授權」,而不是「認證」。(認證涵蓋需要知道使用者資訊)

那麼,回到 OpenID Connect(OIDC)。它在 OAuth 2.0 的基礎上添加了一層「身份認證」的功能。所以授權伺服器也需演身份提供者(Identity Provider,IDP)的角色,並提供關於使用者身份的資訊。

舉個例子,當你透過 Google 帳戶登入某個應用程式時,這個應用程式不僅獲得了存取你 Google 雲端硬碟的權限(這部分是 OAuth 2.0 負責的),還獲取了你的基本身份資訊,比如名字和電子郵件(這部分就是 OIDC 負責的)。

總結一下,OAuth 2.0 負責「授權」,讓應用程式有權限執行某些操作,而 OIDC 則確定「你是誰」,提供身份認證。兩者合作,形成了一個完整的身份驗證和授權解決方案。需要注意的是,身份認證可以透過多種方式來實現,像是使用 JWT 格式的 Token 來傳遞身份資訊。

OAuth 2.0 是一個授權框架,而 IDP 則負責身份認證

從我們上述的OAuth 2.0圖看,授權伺服器(Authorization Server)主要回傳「存取令牌(Access Token)」,用來授權應用程式存取特定資源。如果我們加入OpenID Connect(OIDC),則授權伺服器會同時回傳一些關於使用者的身份資訊(ID Token),這樣應用程式可以知道「你是誰」。

下圖簡單展示了OpenID Connect和OAuth 2.0的區別,關鍵在於OpenID Connect會回傳更完整的身份訊息,而OAuth 2.0只專注於授權。

IDP(身份提供者)只負責身分識別與認證,不包含授權部分。

https://ithelp.ithome.com.tw/upload/images/20240924/20115895TgBJWXW71F.png

  • 上半部分:OpenID Connect 認證
    1. Android App 問:Who are you? : 這步驟代表應用程式(Android App)在詢問用戶的身份。它想要知道「你是誰」。
    2. 用戶向 Google 申請身份證明 : 用戶會向身份提供者(IDP,例如 Google)要求提供一份包含身份資訊的證明文件。這是所謂的「身份認證」(Authentication)。
    3. Google 發出身份證書 : Google 作為身份提供者,發出一個經過簽名的證書,證明用戶的身份。這個證書包含使用者的真實姓名、Email地址等身份資訊,並且經由Google這個「公證人」簽名。
    4. App 接收證書 : Android App 拿到這個身份證明,這樣它就可以確認「你是誰」,例如知道你的名字和Email。
  • 下半部分:OAuth 2.0 假認證(Pseudo-Authentication)
    1. Android App 問:給我一把「通行鑰匙」 : 在OAuth 2.0的流程中,應用程式不會直接要求確認你的身份,而是會向你索取一個「通行鑰匙」(訪問令牌,Access Token)。這把鑰匙允許它存取某些受保護的資源(例如你的帳戶資料)。
    2. 用戶向 Google 申請「通行鑰匙」: 用戶向Google(或其他授權伺服器)請求這把「通行鑰匙」,以便讓應用程式能夠存取特定的API或資源。
    3. Google 發出「通行鑰匙」(Access Token) : Google 這時候不會發出包含身份資訊的證書,而是給了應用程式一個訪問令牌,這個令牌只授權應用程式執行一些操作,並不會傳遞用戶的身份資訊。
    4. App 接收「通行鑰匙」 : Android App 拿到這個「通行鑰匙」後,便可以用它來請求API存取特定的資源,像是你的雲端硬碟資料,但並沒有直接知道你是誰。

OpenID Connect 認證:允許應用程式透過身份提供者(例如 Google)來獲取用戶的身份證明,這樣應用程式不僅能存取資源,還能知道「你是誰」。

OAuth 2.0 授權:主要關注的是授權,應用程式只能透過「通行鑰匙」(Access Token)存取特定資源,但不會得到使用者的身份資訊。

IDP Format

OICD資料由JSON格式來儲存類似的信息,在OIDC中這種JSON對象通常被稱為ID Token。內如基本上如下

  • iss(Issuer): 發行這個Token的身份提供者。
  • sub(Subject): 這個Token是關於哪個用戶的。
  • aud(Audience): 這個Token是給哪個服務提供者的。
  • exp(Expiration): Token的過期時間。
  • iat(Issued At): Token的發行時間。
{
  "iss": "https://accounts.google.com",
  "sub": "1234567890",
  "aud": "your-app-client-id",
  "exp": 1617373200,
  "iat": 1617369600,
  "email": "john.doe@example.com"
  // 其他屬性
}

Security Assertion Markup Language( SAML)

當我們了解了OAuth 2.0和OpenID Connect (OIDC) 這兩個現代化的授權與身份驗證技術後,接下來讓我們來談談SAML (Security Assertion Markup Language)。SAML同樣也是一個用於身份驗證與授權的框架,主要應用於企業級環境中的單一登入(SSO)解決方案。雖然OAuth 2.0和OIDC已成為應用的首選,但SAML在許多傳統企業應用中依然有它的身影在(我還遇過特規SAML….),特別是在需要跨多個應用和服務實現Federated Identity的情境下。

SAML主要涵蓋三個角色

  • Identity Provider(身分提供者) 負責認證使用者身份的系統。以Google為例,當你使用Google登入其他應用時,Google就是身份提供者。IdP的角色是驗證「你是誰」。

  • Service Provider(服務提供者) : 使用者想要訪問的各種線上服務,像是郵件系統或報銷系統。SP依賴IdP進行身份驗證,來決定是否允許使用者存取其資源。

  • User Agent (使用者代理):參與認證和授權過程的軟體,簡單來說就是使用者用來訪問網頁或應用程式的工具,最常見的例子就是瀏覽器。當你使用瀏覽器訪問一個網站(Service Provider,SP)時,瀏覽器就是幫你和網站進行互動的工具。

流程我們以**OASIS提供的圖為例,闡述**使用 SAML服務提供者(Service Provider, SP)身份提供者(Identity Provider, IdP) 之間的身份驗證過程,讓用戶只需要登入一次,就能夠訪問多個應用或系統的資源。
https://ithelp.ithome.com.tw/upload/images/20240924/20115895YHWjiMpQAe.png

Step1 : 用戶請求資源

  • 用戶透過瀏覽器請求訪問 服務提供者 (SP) 上的一個受保護的資源。
  • 服務提供者會檢查該用戶是否已經登入過。如果用戶未登入,服務提供者將拒絕訪問,並啟動身份驗證流程。

Step2 : 將用戶重定向到 IdP 進行身份驗證

  • 用戶尚未登入,SP 將用戶重定向到 身份提供者 (IdP),以請求用戶身份驗證。
  • SP 會向 IdP 發送一個 ,這是一個SAML身份驗證請求,請求 IdP 驗證用戶的身份。

Step3 : IdP 向用戶請求憑證

  • IdP 收到 後,會檢查用戶是否已經在該 IdP 登入過。如果用戶尚未登入,IdP 將要求用戶輸入身份憑證(例如使用者帳號和密碼)。

Step4: 用戶在 IdP 登入

  • 用戶通過瀏覽器輸入憑證(如帳號和密碼)並提交給 IdP
  • IdP 驗證用戶憑證的正確性。如果驗證成功,IdP 會生成一個 SAML聲明 (SAML Assertion),這個聲明包含用戶的身份信息,並經過數位簽章以保證其完整性和真實性。

Step5 : IdP 將 SAML Assertion回傳給 SP

  • IdP 生成的 SAML Assertion中包含用戶的身份資訊,並經過數位簽名來保證其完整性。
  • IdP 通過瀏覽器將簽名的 以HTTP POST的方式發送回 SP

Step6 : SP 驗證 SAML Assertion

  • SP 接收到 SAML 聲明後,對其進行驗證,確保它來自受信的 IdP 並且內容未被篡改。
  • 驗證通過後,SP 認為用戶已經成功登入。

Step7: 用戶獲取受保護資源

  • 驗證成功後,SP 允許用戶訪問其最初請求的受保護資源,流程結束。

SAML 使用的是斷言(Assertion)來傳遞用戶的身份信息。

IDP Format

SAML中,數據通常會以一個XML文件的形式出現,這個文件被稱為「斷言」(Assertion)。斷言中會包含多種元素,例如:

  • Issuer(發行者): 這個斷言是由哪個身份提供者(IdP)發出的。
  • mSubject(主題): 這個斷言是關於哪個用戶的。
  • Conditions(條件): 斷言在什麼情況下有效,例如有效期限。
  • AttributeStatement(屬性聲明): 包含用戶的一些屬性,比如用戶名、郵箱等。
<Assertion>
  <Issuer>https://idp.example.com</Issuer>
  <Subject>john.doe</Subject>
  <Conditions>
    <!-- 條件,比如有效時間 -->
  </Conditions>
  <AttributeStatement>
    <Attribute Name="email">john.doe@example.com</Attribute>
    <!-- 其他屬性 -->
  </AttributeStatement>
</Assertion>

**Identity Provider(**IDP)

上述討論 OIDC(OpenID Connect)和 SAML(安全斷言標記語言)的過程中,Identity Provider(IDP,身份提供者) 扮演了關鍵角色。IDP 負責 身份認證,管理和存儲使用者的認證資料(例如帳號和密碼)。當使用者通過認證後,IDP 會生成一個斷言或令牌,內容不僅包含使用者的身份資訊,還可能包括其他屬性。由於斷言是**加密(大都狀況下會加密)和簽署(必要)**的,因此服務提供者(SP)可以做驗證判斷其真實性。

IDP的身份管理過程:

  • 資料庫存儲:IDP 通常有一個專門的資料庫或是目錄服務LDAP),用來存放使用者的身份資訊,例如帳號、密碼、電子郵件等。這些資料通常會經過加密處理,以保障使用者的隱私和安全。
  • 註冊過程:當使用者首次註冊某個服務時,會提交必要的身份資訊,這些資料會被儲存在 IDP 的資料庫中進行管理。
  • 認證過程:當使用者嘗試登入某個服務,IDP 會檢查使用者提交的身份資料(如帳號和密碼)是否與資料庫中的資料一致。如果一致,IDP 就會認證使用者的身份,允許存取服務。
  • 多因素認證:為了增強安全性,IDP 可能會要求使用多因素認證(MFA),這可能包括除了密碼外還需要短信驗證碼、指紋掃描或臉部辨識等額外的安全步驟。
  • 更新與撤銷:使用者可以隨時更新或修改他們的身份資訊。如果 IDP 發現帳戶有不正常的活動,IDP 可以暫停或撤銷該帳戶的訪問權限,以防止不當使用。
  • 單一登入(SSO):IdP 是實現單一登入的核心元件,允許使用者透過一次驗證即可存取多個相關的系統或應用程式。

IdP 需要遵循相關的標準格式(如 SAML 或 OIDC ),以確保與不同的服務提供者(SP)相容。這種標準化使得不同系統之間的身分資訊交換安全,最重要的是…很多識別授權工具,都是基於這樣的格式設計的…如果不符合標規,那會需要特別對特規去格式處理,非常麻煩。

IDP 是 OIDC 和 SAML 認證流程中的核心,負責管理和驗證使用者的身份,並保障使用者的認證資料安全。透過生成簽署和加密的斷言或令牌,IDP 讓服務提供者可以信任該身份,並授予使用者存取權限。

相信整個聊完,你一定對身分識別資源授權的概念有一個很全面正確的認知! 總結來說:

  • OAuth 2.0 主要是處理「可以存取什麼」的問題。
  • SAML 專注於「讓你在不同系統間自由通行」。
  • OpenID Connect 則是「確認你是誰,然後決定你可以存取什麼」。

希望此篇文章對你有幫助!


上一篇
開發概念建置-單體服務到微服務架構
下一篇
開發觀念建置-關於加密機制
系列文
微服務奇兵:30天Quarkus特訓營25
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言