上一篇看的是 Device Authorization Grant——沒有瀏覽器、但還是需要「使用者」在另一台裝置上參與同意的情境。今天要看的 JWT Bearer 擴展機制,走的是完全不同的路線:不需要使用者即時參與,而是靠 Client 手上已經有的一張「簽好的 JWT」,直接跟 Token 端點換一張全新的 Access Token。
在往下看之前,先解決一個常見疑惑:這裡的 JWT,跟 Day04 拆過的 JWT 格式一樣,但扮演的角色完全不同。
今天內容涵蓋:
JWT Bearer 不是用來讓使用者「登入一次、通行多個系統」;它真正要解決的是:當 Client 不需要、或無法讓使用者即時參與時,要怎麼利用既有的信任關係取得 Access Token。
可以把它想成「拿一張已蓋章的證明,去換 API 的臨時通行證」。Client 先準備一張由可信任對象簽發的 JWT,再把它交給 Authorization Server;伺服器確認簽章、簽發者、使用對象與有效期限都正確後,就會核發 Access Token。整段流程的重點是系統之間交換憑證,不需要使用者當下開啟瀏覽器、登入或按下「允許」。
最典型的例子,是每天半夜自動產生報表的背景服務:它沒有使用者坐在螢幕前操作,卻仍需要存取受保護的 API。服務可以簽出一張短效 JWT 證明自己的身分與授權依據,再拿它換取 Access Token,完成後續工作。
常見的適用場景包括:
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 是另一套平行、獨立的擴展機制。
接著,再依照憑證格式分成不同做法:
這張憑證可以有兩種用途:一種是當成「為什麼可以核發 Access Token」的授權依據;另一種是用來證明「是哪個 Client 提出請求」。
💡Assertion Framework 是共同規則,JWT Bearer 則是使用 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 是由外部身份平台簽發,還是由 Client 自己產生,核心流程都一樣:先取得受信任的 JWT,再用它向 Authorization Server 交換 Access Token。

上圖以「JWT 由外部 Token Service(IdP)簽發」為例,流程可以拆成四個階段:
assertion,送到 Authorization Server 的 /token 端點。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 何時失效 |
iat、nbf |
選填 | 簽發時間,以及從何時開始生效 |
jti |
建議使用 | JWT 的唯一編號,可協助阻擋重放攻擊 |
JWT 必須使用數位簽章,或透過共享密鑰產生訊息驗證碼(MAC,例如 HMAC),讓 Authorization Server 確認 JWT 的來源可信,而且內容沒有被修改。只要簽章錯誤、已過期,或 aud 不是目前的 Authorization Server,請求就會被拒絕並回傳 invalid_grant。驗證成功後,則會收到一般的 Access Token 回應。
| 做法 | 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,再執行一次交換流程。
🔐安全上要注意三件事:
aud必須精準指向接收 JWT 的 Authorization Server,避免 JWT 被拿到其他系統重複使用。- JWT 效期要短,並盡量使用
jti防止同一顆 JWT 被重複使用。- 私鑰或共享密鑰必須妥善保存,Authorization Server 也只能信任事先登記的 Issuer。
把前面的討論收攏成一張表:
| 比較項目 | 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。
綜合本篇內容,可歸納為以下三項:
iss、sub、aud、exp 等資訊是否正確。assertion 時是換取 Access Token 的授權證明;放在 client_assertion 時則只是 Client 的身分證明。本文主要討論第一種。下一篇將介紹 SAML 2.0 Bearer 擴展機制。其核心概念與 JWT Bearer 相近,主要差異在於使用 SAML Assertion 作為交換 Access Token 的授權憑證,適用於已部署傳統 SAML IdP 的企業環境。