iT邦幫忙

2026 iThome 鐵人賽

DAY 11
0
Software Development

30 天把舊 ERP 整合成現代微服務平台:架構治理與工程實作雙軌實戰系列 第 11 篇

Day 11|Keycloak、OAuth 2.0、OIDC 與 JWT:別再把登入和授權混在一起

  • 分享至 

  • xImage
  •  

Keycloak、OAuth 2.0、OIDC、JWT,常常會一起出現在登入設計裡。我想先把它們一個一個分清楚,再沿著登入流程看一次,這樣比較知道每一步到底驗證了什麼。

本篇名詞小筆記

  • Keycloak:開源的身分與存取管理伺服器,負責帳號、角色與 Token 發放;本系列用它擔任集中的身分提供者。
  • OAuth 2.0:授權框架,讓應用程式在受控範圍內取得存取資源的權限。
  • OIDC:OpenID Connect,建立在 OAuth 2.0 之上的身分驗證協定,用來確認登入者身分。
  • JWT:JSON Web Token,一種可攜帶 claims 並以簽章驗證完整性的 Token 格式。
  • PKCE:Proof Key for Code Exchange,用一次性的驗證碼保護授權碼交換流程。
  • Claims:JWT Payload 裡的每一個欄位,例如誰發的(iss)、幾點過期(exp)、有哪些角色(realm_access.roles)。Payload 任何人都解得開,所以要先驗過簽章,這些欄位才能拿來做授權判斷。

今天要解決的問題

有一個問題,我會先提醒自己:如果只看到 Token 有效就放行,就可能漏掉這個人到底能不能查這筆資料。所以使用者能登入,接下來能做哪些事,還要另外確認。測試時也要換不同權限的帳號,才看得到這些差異。

Payload 的內容可以被讀出來,不表示它值得信任,所以 JWT 也不能只看能不能解碼;簽章與 claims 都驗證完成,才有依據使用裡面的資訊。

架構師視角:雙層驗證,內網不預設信任

入口與服務兩邊都驗一次,初看會覺得有點重複。不過,Gateway 可以先擋下無效請求,服務則要確認到自己這裡的請求仍符合要求。即使有人繞過入口,服務也保有自己的檢查。

所以,我會先讓 Gateway 檢查 Token 簽章、issuer 與有效期。請求到了業務服務,再由 Resource Server 獨立驗證同一個 JWT,接著判斷資源權限。每一層把自己的工作做好,才不會只靠「已經經過入口」這個假設。

https://ithelp.ithome.com.tw/upload/images/20260925/20184230GKPmHLJifK.png

圖 Day 11-1:Keycloak OIDC 登入流程。

下游需要依原始呼叫者的身分判斷,知道目前是誰在操作。所以這個系列採用的方式,是讓 Gateway 轉發原本的 Authorization header,不在入口換成另一個服務帳號。

工程師視角:PKCE、Resource Server 與 Token 保管

前端這一段,採用 Authorization Code Flow with PKCE;後端設定 Resource Server,服務帳號再依情境使用 client credentials。前端不使用 Implicit Flow,也不保存長期憑證,這些基本條件要一起確認。

Realm、client 與 role 的設定要能追蹤異動,secret 則放在有權限控管、有異動紀錄的地方,不進 repository 也不進 Log。因為網址可能一路留在瀏覽器歷程、proxy 與存取紀錄中,所以 Token 也不要放進 URL 或 Log。這些地方都值得在測試時多看一次。

issuer 也要逐字確認,包含主機名稱。如果服務連的是容器內部名稱,Token 寫的卻是對外網址,就需要回頭核對設定。遇到 401,再從有權限管控的 Log 查明實際的驗證原因。

策略取捨與限制

取捨 這樣選的理由 何時要重新評估
入口與服務各驗一次 JWT 內網不作為信任邊界 驗證成本成為效能瓶頸時,需先量測再調整
前端採 Authorization Code + PKCE 不需在前端保存 client secret 標準演進或裝置條件改變時
Gateway 原封不動轉發 Authorization header 下游需要原始呼叫者身分做授權 有必須隱藏原始身分的整合情境時
身分管理集中於單一 IdP 帳號與角色治理才可能一致 IdP 可用性影響範圍超出可接受程度時

身分管理集中後,IdP 的可用性會影響登入與 Token 取得。既有的有效 Token 在到期前仍可使用,因此影響主要落在新登入與續期;規劃 Keycloak 要開幾台、Token 有效期設多長、掛掉時怎麼處理,都要照這個特性來,不必當成「Keycloak 一掛,全部服務馬上停」。還有一條要寫進去:Gateway 是把 Keycloak 的公鑰抓回來快取後自己驗簽章,所以 Keycloak 掛掉期間不要重啟 Gateway,否則抓不到公鑰,所有 Token 都驗不過。

驗證方式與衡量指標

除了正常登入,我也會多花一點時間測試不能通過的情況:

測試情境 預期行為 想確認什麼
Token 過期 401,且不因快取而放行 有效期檢查是否真的生效?
issuer 錯誤 401 是否只驗簽章而未驗發行者?
簽章變更或金鑰輪替 401 或依新金鑰驗證成功 金鑰輪替是否會造成中斷?
登出後使用舊 Token 依設計拒絕或於到期後失效 登出語意是否與實作一致?
時鐘偏差 在容許範圍內仍可驗證 容許值是否明確設定?本系列目前沿用 Spring Security 預設值
IdP 無法使用 既有 Token 可用,新登入失敗且錯誤明確 降級行為是否可預期?

JWT 採無狀態驗證時,登出未必會讓已發出的 Token 立刻失效。登出後舊 Token 還能不能用,這件事要先講清楚。把預期行為寫好、測過,使用者和團隊才會有一致的理解。

今天先整理到這裡

今天先把登入流程中的角色分開來看。接下來,我想繼續整理登入之後的事情:這個人可以做什麼,又能看到哪些資料?下一篇,就從角色、資源與資料範圍開始。

參考資料

  1. OpenID Foundation, OpenID Connect Core,查閱日期:2026-09-24。
  2. IETF, OAuth 2.0 RFC 6749,查閱日期:2026-09-24。
  3. Keycloak, Keycloak Securing Applications,查閱日期:2026-09-24。

上一篇
Day 10|Spring Cloud Gateway:Route、Predicate、Filter 如何分工
下一篇
Day 12|RBAC 還不夠:把角色、資源與資料範圍分開
系列文
30 天把舊 ERP 整合成現代微服務平台:架構治理與工程實作雙軌實戰 共 13 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言