iT邦幫忙

2026 iThome 鐵人賽

DAY 14
0
Software Development

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

Day 14|JWT Bearer 擴展機制:拿一張簽好的憑證換 Access Token

  • 分享至 

  • xImage
  •  

前言

上一篇看的是 Device Authorization Grant——沒有瀏覽器、但還是需要「使用者」在另一台裝置上參與同意的情境。今天要看的 JWT Bearer 擴展機制,走的是完全不同的路線:不需要使用者即時參與,而是靠 Client 手上已經有的一張「簽好的 JWT」,直接跟 Token 端點換一張全新的 Access Token。

在往下看之前,先解決一個常見疑惑:這裡的 JWT,跟 Day04 拆過的 JWT 格式一樣,但扮演的角色完全不同。

今天內容涵蓋:

  1. JWT Bearer 擴展機制要解決的問題
  2. JWT Bearer 規格從哪裡來
  3. JWT 的兩種用途
  4. JWT Bearer 實際怎麼運作
  5. 跟 Day04 JWT 的差異總整理

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

JWT Bearer 不是用來讓使用者「登入一次、通行多個系統」;它真正要解決的是:當 Client 不需要、或無法讓使用者即時參與時,要怎麼利用既有的信任關係取得 Access Token

可以把它想成「拿一張已蓋章的證明,去換 API 的臨時通行證」。Client 先準備一張由可信任對象簽發的 JWT,再把它交給 Authorization Server;伺服器確認簽章、簽發者、使用對象與有效期限都正確後,就會核發 Access Token。整段流程的重點是系統之間交換憑證,不需要使用者當下開啟瀏覽器、登入或按下「允許」。

最典型的例子,是每天半夜自動產生報表的背景服務:它沒有使用者坐在螢幕前操作,卻仍需要存取受保護的 API。服務可以簽出一張短效 JWT 證明自己的身分與授權依據,再拿它換取 Access Token,完成後續工作。

常見的適用場景包括:

  • 伺服器對伺服器自動化:背景排程、批次作業或 Service Account 用 JWT 換取短效 Access Token,不需要保存長效帳密,也不需要使用者即時參與。
  • 企業級 SaaS 整合:Salesforce、Atlassian、DocuSign 等服務,允許受信任的合作應用程式用預先簽好的 JWT 直接換取 Access Token,不必每次執行完整的 Authorization Code 流程。
  • 身份聯合(Federation):Client 把系統 A 簽發的 JWT 交給系統 B,換取系統 B 可接受的 Access Token。這種情境可能出現在 SSO 架構背後,但 JWT Bearer 關心的是「如何交換 API Token」,而不是「如何讓使用者免登入」。

二、JWT Bearer 規格從哪裡來

OAuth 2.0 一開始只定義了幾種常見的授權流程,但後來出現新的需求:Client 手上已經有一張可信任的憑證,能不能直接拿它來換 Access Token?

JWT Bearer 並不是完全獨立設計的機制。它和 SAML 2.0 Bearer 都遵循一套稱為 Assertion Framework 的共同規則,專門規範「如何拿一份受信任的憑證,向 OAuth 2.0 的 Token 端點申請 Access Token」。這套框架只處理以 JWT 或 SAML Assertion 作為憑證的情境,並不包含之後會介紹的 Token Exchange;Token Exchange 是另一套平行、獨立的擴展機制。

接著,再依照憑證格式分成不同做法:

  • 憑證使用 JWT 格式,就是這篇介紹的 JWT Bearer
  • 憑證使用 SAML Assertion 格式,就是之後介紹的 SAML 2.0 Bearer

這張憑證可以有兩種用途:一種是當成「為什麼可以核發 Access Token」的授權依據;另一種是用來證明「是哪個 Client 提出請求」。

💡Assertion Framework 是共同規則,JWT Bearer 則是使用 JWT 實作這套規則的方式。

三、JWT 的兩種用途

JWT Bearer 規格允許 JWT 扮演兩種角色,差別在於它是用來提供授權依據,還是只用來證明 Client 身分

用途 JWT 代表的意義 使用的參數
JWT Bearer Grant 已簽核的授權證明;Authorization Server 驗證後,可以據此核發 Access Token assertion
JWT Client Authentication Client 的身分證明;只證明是哪個 Client 提出請求 client_assertion

可以把前者想成「已核准的申請單」,後者則像「員工證」。員工證只能證明來的人是誰,不代表某項申請已經獲准,因此 JWT Client Authentication 還必須搭配 Authorization Code、Client Credentials 等授權方式。

同一個 Token Request 可以同時帶上兩種 JWT:一顆提供授權依據,另一顆驗證 Client 身分。本文接下來只討論第一種,也就是用 assertion 裡的 JWT 交換 Access Token。

四、JWT Bearer 實際怎麼運作

不論 JWT 是由外部身份平台簽發,還是由 Client 自己產生,核心流程都一樣:先取得受信任的 JWT,再用它向 Authorization Server 交換 Access Token。

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

上圖以「JWT 由外部 Token Service(IdP)簽發」為例,流程可以拆成四個階段:

  1. 取得 JWT:Client 向 Token Service 請求 JWT;Token Service 建立並簽署後回傳。如果採用 Client 自己簽發 JWT 的模式,這一步會直接在 Client 內完成。
  2. 交換 Access Token:Client 把 JWT 放進 assertion,送到 Authorization Server 的 /token 端點。
  3. 驗證 JWT:Authorization Server 檢查簽章、簽發者、代表的主體、使用對象與有效期限。驗證通過後,回傳 Access Token。
  4. 呼叫 API:Client 帶著 Access Token 存取 Resource Server,不會直接拿原本的 JWT 呼叫 API。

Token Request 的核心參數如下:

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
&assertion={signed-jwt}

其中 assertion 就是那顆已簽名的 JWT。JWT 內最重要的資訊包括:

Claim 必要性 用途
iss 必填 誰簽發這顆 JWT
sub 必填 JWT 代表哪個使用者或服務帳號
aud 必填 這顆 JWT 要交給哪個 Authorization Server
exp 必填 JWT 何時失效
iatnbf 選填 簽發時間,以及從何時開始生效
jti 建議使用 JWT 的唯一編號,可協助阻擋重放攻擊

JWT 必須使用數位簽章,或透過共享密鑰產生訊息驗證碼(MAC,例如 HMAC),讓 Authorization Server 確認 JWT 的來源可信,而且內容沒有被修改。只要簽章錯誤、已過期,或 aud 不是目前的 Authorization Server,請求就會被拒絕並回傳 invalid_grant。驗證成功後,則會收到一般的 Access Token 回應。

兩種常見的 JWT 來源

做法 JWT 由誰簽發 信任如何建立 代表案例
Client 自己簽發 後端程式使用自己的私鑰產生 JWT Authorization Server 預先登記並信任對應的公鑰 Google Service Account
外部身份平台簽發 Token Service/IdP 簽發,Client 負責轉交 Authorization Server 預先信任該 Issuer 的公鑰或共享密鑰 企業內部 IdP 串接

第一種最常見的例子是 Google Service Account:後端程式使用 Service Account 的私鑰簽出一顆短效 JWT,再把它送到 Google 的 Token 端點交換 Access Token,最後使用 Access Token 呼叫 Google API。整個過程不需要使用者登入或按下同意。

第二種則常見於企業內部的身份平台整合:公司 IdP 先簽發 JWT,後端服務只負責把它轉交給 Authorization Server,再換取目標 API 接受的 Access Token。上方的流程圖呈現的就是這種做法。

💡兩種做法只有「JWT 從哪裡來」不同,後半段都一樣:Client 把 JWT 當成 assertion 送到 Token 端點,換回 Access Token。

JWT Bearer 通常不會搭配 Refresh Token。需要新的 Access Token 時,Client 會重新取得或簽發一顆短效 JWT,再執行一次交換流程。

🔐安全上要注意三件事:

  1. aud 必須精準指向接收 JWT 的 Authorization Server,避免 JWT 被拿到其他系統重複使用。
  2. JWT 效期要短,並盡量使用 jti 防止同一顆 JWT 被重複使用。
  3. 私鑰或共享密鑰必須妥善保存,Authorization Server 也只能信任事先登記的 Issuer。

五、跟 Day04 JWT 的差異總整理

把前面的討論收攏成一張表:

比較項目 Day04 的 JWT 這篇的 JWT Bearer
本質 Token 的格式,通常是登入流程最後拿到手的 Access Token/ID Token 本身 一種 OAuth 擴展 Grant Type,是 Client 拿去跟 Token 端點換 Access Token 的輸入憑證
出現的階段 流程的終點 流程的起點
對應 grant_type 不涉及,是拿到 Token 之後怎麼用的問題 grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer
常見情境 前端拿著 Access Token 呼叫 API 服務對服務(M2M)、身份聯合(Federation)、使用者模擬(Impersonation)

兩者唯一的共同點,就是都採用 JWT 這個格式——這也是為什麼很容易被搞混,但只要記住「這顆 JWT 現在扮演的是結果,還是輸入」,就能快速分清楚。


小結

JWT Bearer 的核心,是讓 Client 在不需要使用者即時參與的情況下,用一顆受信任、已簽名的 JWT 向 Authorization Server 交換 Access Token。這顆 JWT 不是拿來直接呼叫 API,而是取得 Access Token 前使用的「換票憑證」。

Google Service Account 就是常見例子:後端程式先用私鑰簽出短效 JWT,再向 Google 交換可呼叫 API 的 Access Token。

綜合本篇內容,可歸納為以下三項:

  1. 這裡的 JWT 是流程的輸入,不是最後拿去呼叫 API 的 Token:它的用途是向 Authorization Server 證明這次交換有可信任的依據。
  2. Authorization Server 會驗證 JWT 是否可信:除了檢查簽章,也會確認 isssubaudexp 等資訊是否正確。
  3. JWT 可以作為授權依據,也可以只用來驗證 Client 身分:放在 assertion 時是換取 Access Token 的授權證明;放在 client_assertion 時則只是 Client 的身分證明。本文主要討論第一種。

下一篇將介紹 SAML 2.0 Bearer 擴展機制。其核心概念與 JWT Bearer 相近,主要差異在於使用 SAML Assertion 作為交換 Access Token 的授權憑證,適用於已部署傳統 SAML IdP 的企業環境。

參考資源


上一篇
Day 13|Device Authorization Grant 擴展機制:沒有瀏覽器也能授權
系列文
從登入到授權-現代軟體的身分架構指南14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言