iT邦幫忙

2026 iThome 鐵人賽

DAY 15
0
Software Development

從登入到授權-現代軟體的身分架構指南系列 第 15 篇

Day 15|SAML 2.0 Bearer 擴展機制:讓舊系統無痛接軌 OAuth 2.0

  • 分享至 

  • xImage
  •  

前言

Day05 與本文使用的都是 SAML Assertion(SAML 驗證聲明,也就是由 IdP 簽發的身份證明),但用途並不相同。

在 SSO 流程中,SAML Assertion 是使用者完成登入後的身份驗證結果(Authentication Result)。IdP 透過瀏覽器將它傳給 SP,SP 驗證後便建立使用者的登入狀態。

在本文介紹的 SAML 2.0 Bearer 流程中,Client 則將已取得的 SAML Assertion 送到 OAuth 2.0 的 Token 端點,用來交換 Access Token。這通常是後端系統之間的處理流程,不需要使用者再次登入,也不依賴瀏覽器重新導向。

簡單來說,同樣是 SAML Assertion,SSO 把它當登入結果;SAML 2.0 Bearer 則把它當換取 Access Token 的輸入憑證。

今天內容涵蓋:

  1. SAML 2.0 Bearer 擴展機制要解決的問題
  2. SAML 2.0 Bearer 與 JWT Bearer 的關係
  3. 兩種用途在 SAML 中的實作差異
  4. SAML 2.0 Bearer 實際怎麼運作
  5. SAML SSO 與 SAML 2.0 Bearer 的差異

一、SAML 2.0 Bearer 擴展機制要解決的問題

Day05 講過,很多企業內部系統早就用 SAML 做 SSO:員工開瀏覽器,被導到 SAML IdP 登入,IdP 簽發一份 SAML Assertion 送回應用程式,使用者就進去了。但這一切都建立在「有瀏覽器、有使用者在場」的前提上。

現實中還有另一種情境:某個系統(可能是 API Gateway、後端服務、中介層)手上已經有一張代表某個使用者身份的 SAML Assertion,但接下來要呼叫的 API 只接受 OAuth 2.0 的 Access Token,不認得 SAML Assertion。此時使用者身份已完成驗證,整體流程通常也不涉及瀏覽器,因此無須再次登入或重新導向。

SAML 2.0 Bearer 擴展機制(RFC 7522) 要解決的就是這個問題:讓 Client 拿著一張已簽署、來自受信任 IdP 的 SAML Assertion,直接向 OAuth 2.0 的 Token 端點換一個 Access Token。它和 Day14 的 JWT Bearer 解決的是同一類問題,差別只在 Assertion 的格式是 XML 的 SAML 還是 JSON 的 JWT。


二、SAML 2.0 Bearer 與 JWT Bearer 的關係

OAuth 2.0 先制定了一套共通的 Assertion Framework(身份聲明框架),說明 Client 如何使用既有的身份聲明交換 Access Token,或證明 Client 自身的身份。這套框架只定義共同的使用方式,並不限制身份聲明必須採用哪一種格式。

SAML 2.0 Bearer 與 Day14 介紹的 JWT Bearer 都依循這套框架。兩者的核心用途相近,主要差別在於資料格式與常見使用情境:

比較項目 SAML 2.0 Bearer JWT Bearer
身份聲明格式 SAML Assertion(XML) JWT(JSON)
Token 交換類型 saml2-bearer jwt-bearer
常見來源 企業 SAML IdP、既有企業系統 OAuth/OIDC 系統、Service Account
常見情境 既有企業系統銜接 OAuth 後端服務與自動化程式存取 API

兩者都可以用來交換 Access Token,或作為 Client 身份驗證的依據,也都必須檢查簽發者、受眾、有效期限與簽章。兩者核心概念大致相同,主要差在憑證格式。


三、兩種用途在 SAML 中的實作差異

Day14 已介紹過 JWT Bearer 可以作為授權依據,也可以用來驗證 Client 身份。SAML 2.0 Bearer 沿用相同設計,因此這裡不再重複說明兩種用途,而是聚焦於改用 SAML Assertion 後的差異。

用途 Token Request 參數 Day14 的 JWT 表示方式 本文的 SAML 表示方式
作為授權依據 assertion 透過 sub 表示使用者或服務身份 透過 Subject/NameID 表示使用者或資源擁有者
驗證 Client 身份 client_assertion sub 對應 Client 的 client_id Subject/NameID 對應 Client 的 client_id

可以看出,兩種機制使用的參數與用途並沒有改變,真正不同的是憑證格式與欄位名稱:

  • JWT 使用 JSON 格式,透過 iss、sub、aud、exp 等 Claims 表達身份與使用限制。
  • SAML Assertion 使用 XML 格式,改由 Issuer、Subject、AudienceRestriction、NotOnOrAfter 等元素表達相同概念,並另外檢查 Recipient 是否指向正確的 Token 端點。

四、SAML 2.0 Bearer 實際怎麼運作

SAML 2.0 Bearer 的交換流程與 Day14 的 JWT Bearer 幾乎相同;兩者真正的差異不在流程,而在於送入 Token 端點的憑證格式與驗證方式。

https://ithelp.ithome.com.tw/upload/images/20260914/20181928gE3ho6xf76.png

因此,這裡不再重複拆解與 Day14 相同的流程,只整理改用 SAML Assertion 後需要注意的部分:

  1. 輸入憑證不同:JWT Bearer 傳送已簽署的 JWT;SAML 2.0 Bearer 則傳送經過編碼的 SAML Assertion。
  2. Token Request 類型不同:兩者都使用 assertion 參數,但 grant_type 分別是 jwt-bearer 與 saml2-bearer。
  3. 身份資訊的表示方式不同:JWT 使用 iss、sub、aud、exp;SAML 則使用 Issuer、Subject、AudienceRestriction 與 NotOnOrAfter。
  4. 驗證方式不同:JWT 驗證 JWT 簽章與 Claims;SAML 除了驗證 XML 簽章與內容,還會檢查 Recipient 是否指向正確的 Token 端點,以及 Assertion 是否已被重複使用。

Token Request 的核心參數如下:

grant_type=urn:ietf:params:oauth:grant-type:saml2-bearer
&assertion={base64url-encoded-saml-assertion}

其中 assertion 就是那份已簽署並經過 Base64url 編碼的 SAML Assertion,是交換 Access Token 的輸入憑證,不會直接用來呼叫 API。SAML Assertion 內最重要的資訊包括:

元素/屬性 必要性 用途
Issuer 必填 誰簽發這份 SAML Assertion
Subject/NameID 必填 Assertion 代表哪個使用者或 Client
AudienceRestriction/Audience 必填 這份 Assertion 要交給哪個 Authorization Server
SubjectConfirmation 必填 確認這是一份 Bearer Assertion
NotOnOrAfter 必填 Assertion 何時失效
Recipient 條件式 指定接收 Assertion 的 Token 端點
Signature 必填 證明來源可信,且內容未遭竄改

只要簽章無效、Assertion 已過期或使用對象不符,請求就會被拒絕;驗證成功後,則會收到一般的 Access Token 回應:

{
  "access_token": "eyJh...R76eO",
  "token_type": "Bearer",
  "expires_in": 3600
}

💡安全提醒: Authorization Server 必須確認 Assertion 由受信任的 IdP 簽發,並驗證 XML 簽章、Audience、Recipient 與有效期限;同時記錄已使用的 Assertion ID,避免重放攻擊。


五、SAML SSO 與 SAML 2.0 Bearer 的差異

兩者使用相同的 SAML Assertion 格式,但目的與傳輸方式不同:

比較項目 Day05 SSO(Web Browser SSO Profile) Day15 SAML 2.0 Bearer(RFC 7522)
使用場景 使用者用瀏覽器登入 Web 應用程式 系統/服務拿已有的 SAML Assertion 去換 OAuth Access Token
Assertion 的角色 直接就是「登入結果」,SP 收到後直接信任、建立登入狀態 只是換票的輸入憑證,最後真正拿去呼叫 API 的是換回來的 Access Token
傳輸方式 HTTP Redirect(送 AuthnRequest)/HTTP POST(送 Assertion),都經過瀏覽器 直接 POST 到 OAuth Token 端點(application/x-www-form-urlencoded),走後端對後端
是否需要瀏覽器 需要,Redirect/POST binding 都依賴瀏覽器重新導向 通常不需要,使用者不會感覺到這個過程在發生
換回來的東西 SAML Assertion 本身 OAuth 2.0 Access Token
目的 讓使用者「登入一次、多處通行」 讓已經存在的身份驗證結果,延伸到 OAuth 保護的 API/資源

小結

SAML 2.0 Bearer 是拿已簽署的 SAML Assertion,向 OAuth 2.0 的 Token 端點交換 Access Token,讓既有身份驗證結果延伸到 OAuth 保護的 API。

本文的重點可歸納為以下三項:

  • SAML 2.0 Bearer 與 JWT Bearer 都建立在身份聲明框架之上,兩者用途相近,主要差別在於使用的身份聲明格式不同。
  • 一樣有當 Authorization Grant、當 Client Authentication 兩種獨立用法,可分開也可合併使用。
  • 跟 Day05 的 SAML 不是同一種角色:Day05 的 SAML Assertion 是瀏覽器登入的結果;這篇的 SAML 2.0 Bearer 是系統換票的輸入,過程通常沒有瀏覽器參與。

下一篇要看的是 Token Exchange(RFC 8693),把「拿既有憑證換 Access Token」這個概念做得更通用,不限定輸入輸出格式,還會明確定義「模擬」跟「委派」兩種語意,特別適合微服務之間互相呼叫的場景。


參考資源


上一篇
Day 14|JWT Bearer 擴展機制:拿一張簽好的憑證換 Access Token
下一篇
Day 16|Token Exchange 擴展機制:一個 Token 換一個更合身的 Token
系列文
從登入到授權-現代軟體的身分架構指南 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言