Upgrade to Pro — share decks privately, control downloads, hide ads and more …

MCP OAuth 2.0 Workshop: 讓 AI Agent、MCP Server、C...

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →
Avatar for Bo-Yi Wu Bo-Yi Wu
October 26, 2026

MCP OAuth 2.0 Workshop: 讓 AI Agent、MCP Server、CLI 安全登入

2026 年 10 月 14 日,我在 Hello World Dev Conference 2026 帶了一場 90 分鐘的實作工作坊:「讓 AI Agent、MCP Server、CLI 安全登入」。這篇文章把工作坊的觀念與練習路線整理下來,讓沒到場的朋友也能從自己的筆電開始,走過一次 MCP 的授權流程。

當 Agent 能讀文件、查工單、寫入資料,接上工具只是開始。真正要回答的是:這次操作代表誰?可以做哪些事?這顆 Token 能用在哪個服務?出事後,要怎麼停止它的權限?

Blog: https://blog.wu-boy.com/2026/10/ai-agent-mcp-cli-secure-login-workshop-zh-tw/
Workshop: https://github.com/go-training/mcp-oauth2-workshop

Avatar for Bo-Yi Wu

Bo-Yi Wu

October 26, 2026

More Decks by Bo-Yi Wu

Other Decks in Technology

Transcript

  1. Hello World Dev Conference 2026 · Workshop Client Signet MCP

    OAuth 2.0 MCP Server tools/call 401 + resource_metadata Workshop PKCE 登入 Access Token 讓 AI Agent、MCP Server 與 CLI 安全登入 Bearer <token> MCP Authorization 2026-07-28 Kong Gateway 2026/10/14 · 13:30–15:00 OAuth 2.0 + PKCE Signet 200 OK github.com/go-training/mcp-oauth2-workshop
  2. 角色 一次授權,四個參與者 Client Browser Claude Code Codex CLI 瀏覽器 (你)

    代表你登入、保管 登入帳號,確認這個 Token,每次呼叫 MCP App 要拿哪些權限,按 都帶上它。 下允許。 Authorization Server Signet 驗證身分、徵得同意、 簽發 Token,公開驗簽 用的 JWKS。 Resource Server MCP Server 持有工具與資料。 驗 Token,決定放不 放行。 Client ID 是公開識別,不是密碼。CLI 屬於 public Client,沒有 client secret,所以要靠 PKCE 保護登入流程。 MCP OAuth 2.0 Workshop 02 / 19
  3. 課程路線 每一關回答一個問題 01 02 03 04 06 05 10 分

    15 分 25 分 20 分 10 分 課後選修 沒有授權會 怎樣? Client 怎麼知道 去哪登入? 怎麼證明你 是誰? 你能做什麼、能 去哪? 多個服務怎麼共 用入口? 撤銷後會立刻失 效嗎? 任何人都能呼叫所有 工具 401 → PRM → AS metadata Authorization Code + PKCE,Server 驗 JWT scope、audience、 subject 隔離 Kong 集中驗 Token 離線驗證的限制 程式是完整可執行的完成版。重點不是手刻 OAuth,而是看懂每個請求、每一次拒絕代表什麼。 MCP OAuth 2.0 Workshop 03 / 19
  4. Lab 01 · 沒有授權 MCP Server 只是一個 HTTP 端點 Lab

    01 的 Server 不檢查任何東西,所以呼叫一定 成功。 Client MCP Server Claude Code / Codex Lab 01 · 無授權 1 tools/call whoami 不知道呼叫者是誰 沒有 Authorization header 分不出讀取與寫入 2 200 OK 能連到這個 port 的程式,就能用全部工具 3 tools/call create_note 工具:whoami、list_notes、create_note。筆記存在記憶 體裡。 任何人都能寫入 4 200 OK 不知道你是誰 也無從限制你能做什麼 MCP OAuth 2.0 Workshop 04 / 19
  5. Lab 02 · 概念 兩份 metadata,把 Client 帶到登入頁 MCP Server

    GET /.well-known/oauth-protected-resource/mcp { Signet GET AS metadata(依 issuer 建構) { "resource": "http://localhost:8000/mcp", "issuer": "https://signet.wu-boy.com", "authorization_servers": [ "authorization_endpoint": "…", "https://signet.wu-boy.com" "token_endpoint": "…", ] "jwks_uri": "…", } "code_challenge_methods_supported": ["S256"] Protected Resource Metadata(PRM):我是哪個資源、信 } 任哪個 Authorization Server。這是 MCP Server 自己的端點, 不是另一台伺服器。 AS metadata:去哪登入、去哪換 Token、去哪拿公鑰,以及 支援哪種 PKCE。 MCP OAuth 2.0 Workshop 05 / 19
  6. Lab 02 · Sequence Authorization Server Discovery Client MCP Server

    Signet Claude Code / Codex Resource Server · :8000 Authorization Server 1 GET /mcp 未帶 Token 2 401 Unauthorized WWW-Authenticate: Bearer resource_metadata="…" 3 GET resource_metadata 指定的 URL /.well-known/oauth-protected-resource/mcp 4 200 PRM resource、authorization_servers 選定 authorization_servers 裡的 issuer 5 GET AS metadata 依 issuer 建構 well-known URL 6 200 AS metadata authorization_endpoint、token_endpoint、jwks_uri、S256 確認 metadata 的 issuer 與選定值完全一致 Lab 02 到此結束,不需要登入。這一關即使帶有效 Token 也回 401。 06 / 19
  7. Lab 03 · 概念 PKCE:先給鎖頭,最後才拿出鑰匙 code_verifier Client 產生的隨機字串,一直留在 Client 手上。

    授權階段 → code_challenge SHA-256 base64url 放進授權網址,讓 Signet 先記下來。method=S256 換 Token 階段 只送 challenge 送出 verifier 瀏覽器帶回的是授權碼 code,還不是 Token。 Signet 確認 SHA-256(verifier) 等於當初的 challenge。攔 截到 code 的人沒有 verifier,換不到 Token。 同一個流程還有兩道檢查:state 確認 callback 屬於這次登入;iss(RFC 9207)確認回應來自預期的 Authorization Server。 MCP OAuth 2.0 Workshop 07 / 19
  8. Lab 03 · Sequence 1/2 登入授權:瀏覽器帶回的是 code,不是 Token Client 瀏覽器(你)

    Signet Claude Code / Codex 登入與同意 Authorization Server 產生 state 與 code_verifier,算出 code_challenge 1 開啟授權網址 2 GET authorization_endpoint client_id · resource · scope · state · code_challenge (S256) 登入練習帳號,確認 App 與權限,按允許 3 302 → redirect_uri code · state · iss 4 GET 127.0.0.1:8765/callback code · state · iss 檢查 state 與 iss 授權網址只帶 code_challenge;verifier 留在 Client。 08 / 19
  9. Lab 03 · Sequence 2/2 換 Token,然後帶 Token 呼叫 MCP

    Client Signet MCP Server Claude Code / Codex Authorization Server Resource Server · :8000 1 POST token_endpoint code · code_verifier · client_id · redirect_uri · resource SHA-256(verifier) = challenge? 2 Access Token 3 tools/call whoami Authorization: Bearer <token> 驗簽章、iss、aud、exp、type 4 200 · subject 瀏覽器登入狀態不會自動附到 MCP 請求;每次呼叫都要帶 Access Token。 09 / 19
  10. Lab 03 · 概念 MCP Server 收到 Token 後問五個問題 Access

    Token payload 示意,非實際內容 // header: alg RS256, kid → 從 JWKS 找公鑰 簽章 用 Signet 的 JWKS 驗 RS256,確認沒被竄改 iss 是不是我信任的 Signet 簽發的? aud 是不是發給我這台 Server 的? exp 過期了沒有? type 必須是 access;refresh token 或 ID token 不能呼 叫 MCP sub 通過後,用它辨識「你是誰」,whoami 回傳的就是它 { "iss": "https://signet.wu-boy.com", "aud": "http://localhost:8000/mcp", "sub": "練習帳號識別值", "exp": 到期時間, "type": "access", "scope": "notes:read" } RS256 + JWKS 是本教材的選擇;MCP 規範並未強制使用 JWT。 10 / 19
  11. Lab 04 · 概念 401 和 403 是兩種不同的「不行」 401 403

    Unauthorized insufficient_scope 我無法接受這顆 Token 我知道你是誰,但你不能做這件事 沒帶 Token,或 Token 無效、過期 Token 有效、身分確定 aud 不符:這顆 Token 是發給別台 Server 的 只有 notes:read,卻呼叫 create_note 怎麼辦 為這台 Server 的 resource 重新取得 Token 怎麼辦 用更多 scope 重新授權;舊 Token 不會自動 升級 第三道邊界是 subject:同一台 Server、同樣的權限,不同帳號仍只看得到自己的筆記。 MCP OAuth 2.0 Workshop 11 / 19
  12. Lab 04 · Sequence scope:讀得到,不代表寫得進去 Client Signet Server A Claude

    Code / Codex Authorization Server resource :8000/mcp 1 登入授權 resource = :8000/mcp · scope = notes:read 2 讀取 Token 3 list_notes 4 200 筆記清單 5 create_note 同一顆讀取 Token 6 403 insufficient_scope 不新增筆記 同一個帳號重新授權,要求更多權限 7 登入授權 scope = notes:read notes:write 8 讀寫 Token(新的一顆) 9 create_note 10 200 新增成功 notes:read 控制入口,notes:write 控制寫入工具。 12 / 19
  13. Lab 04 · Sequence audience:A 的 Token 打不進 B Client

    Signet Server B Claude Code / Codex Authorization Server resource :8001/mcp 手上有一顆發給 :8000 的讀取 Token 1 whoami 帶 A 的 Token(刻意的負向測試) aud ≠ http://localhost:8001/mcp 2 401 Unauthorized 為 Server B 取得專屬的 Token 3 登入授權 resource = :8001/mcp · scope = notes:read 4 B 的 Token 5 whoami 帶 B 的 Token 6 200 · subject 同一個帳號、同樣的 scope,換一台 Server 就要一顆新的 Token。 13 / 19
  14. Lab 06 · 概念 入口驗證交給 Gateway,業務權限留在服務 Signet Kong + mcp-oauth2

    發 Token 守入口 MCP Backend 管工具與資料 使用者登入與同意授權 回 401 challenge、提供 PRM 驗 Gateway 共享憑證與身 簽發 Token 驗 JWT:簽章、iss、aud、exp 分 headers 公開 JWKS 檢查入口 scope notes:read create_note 仍要求 notes:write 依 subject 隔離資料 信任邊界 backend 不對外發布 port,只在私有網路接收 Kong 的請求。只送一個 X-MCP-Subject: admin header 騙不 取捨 Gateway 多一個要維運的服務。只有一台 MCP Server 時,Lab 04 的自行驗證仍然適用。 過它。 MCP OAuth 2.0 Workshop 14 / 19
  15. Lab 06 · Sequence 1/2 Kong 守入口:401、PRM 與 JWT 驗證

    Client Signet Kong Claude Code / Codex Authorization Server mcp-oauth2 · :9000 1 GET /mcp 未帶 Token 2 401 + resource_metadata PRM 由 Gateway 提供 3 PKCE 登入 resource = http://localhost:9000/mcp 4 Access Token 5 tools/call whoami Authorization: Bearer <token> 離線驗 JWT:簽章、iss、aud、exp 入口 scope:notes:read Kong 不代替使用者登入;登入仍由 Client 向 Signet 完成。 15 / 19
  16. Lab 06 · Sequence 2/2 入口通過,不代表能用所有工具 Client Kong MCP Backend

    Claude Code / Codex mcp-oauth2 · :9000 私有網路 1 轉送 whoami Gateway 共享憑證 + 身分 headers 驗 Gateway 憑證,檢查工具權限 2 200 · subject 經 Kong 回傳 同一顆只有 notes:read 的 Token,改呼叫 create_note 3 tools/call create_note 4 入口通過,轉送 5 403 缺少 notes:write 由 backend 拒絕 Kong 驗入口,MCP backend 管工具與資料權限。 16 / 19
  17. Lab 05 · 課後選修 撤銷成功 ≠ 立刻被拒絕 Client Signet MCP

    Server Claude Code / Codex Authorization Server Resource · :8000 本教材的 Server 與 Kong plugin 都離線驗 JWT,不會每次向 Signet 查撤銷狀態。 1 PKCE 登入 撤銷不改變簽章,未過期的 Token 仍可能通過 2 Access Token RFC 7009:已撤銷或未知的 Token 也可能回 200 3 call 需要即時拒絕時,再設計 introspection 或其他 撤銷傳播機制 4 200 5 POST revocation endpoint client_id · token · hint=access_token 6 200 Revocation accepted 7 call(同一顆 Token) 簽章仍有效、尚未過期 8 200(仍然通過) public Client 撤銷只需 client_id 與 Token,不需要 secret。 17 / 19
  18. 重點回顧 帶走這七件事 401 + PRM 告訴 Client 去哪登入;Server 不代替 Client

    登入 public Client 沒有 secret,靠 PKCE 保護授權碼 每次呼叫 MCP 都要帶 Access Token Server 驗簽章、iss、aud、exp、type 401 是 Token 不被接受;403 是權限不夠 Gateway 集中入口驗證,工具與資料權限仍留在服務 撤銷不等於立即失效,離線驗證要另外處理 MCP OAuth 2.0 Workshop 18 / 19
  19. Q&A Q&A 教材 github.com/go-training/ mcp-oauth2-workshop MCP OAuth 2.0 Workshop 規範

    modelcontextprotocol.io Authorization 2026-07-28 Gateway github.com/go-signet/ kong-mcp-oauth2 19 / 19