MCP 伺服器驗證實現指南:使用最新規範
為 MCP 伺服器在 2025-06-18 規範下的驗證合規實現要點提供指引。
幾日前(2025 年 6 月 18 日),MCP(Model Context Protocol)團隊發佈了最新版的 MCP 規範(2025-06-18)。今次更新對驗證規範有關鍵更改:MCP 伺服器不再作為 授權伺服器 發出 access token,而是作為 資源伺服器 消耗 access token 及提供資源。
作為 MCP Auth (一款隨插即用的 MCP 伺服器驗證庫)的維護者之一,我已經在該項目中支援了最新 MCP 驗證規範。根據實際經驗,本文會教你如何為你的 MCP 伺服器實現符合最新規範的驗證功能。
本文會幫你:
- 理解新 MCP 驗證規範下 MCP 驗證如何運作
- 釐清 MCP 伺服器作為資源伺服器需要根據 MCP 驗證規範實現什麼
- 為你的 MCP 伺服器如何落實符合最新 MCP 驗證規範的驗證支援提供指導
- 指出實現 MCP 驗證規範時容易被忽略的地方及安全問題
請留意,本文:
- 假設讀者具備基本 JWT(JSON Web Token)知識。文中不會詳細講解 JWT 結構、簽名驗證及其他基礎。詳情請參考 Auth Wiki - JWT
- 不會深入介紹 MCP 驗證規範所依賴的各個 RFC,只會提供符合同類 RFC 要求的實現做法
- 不會討論 MCP Client 及授權實現與互動細節。相關內容通常由支援 MCP 規範的 LLM 客戶端與授權伺服器提供者實現。MCP Server 開發者無須亦不能干涉。詳情請參考 OAuth Client 與 Authorization Server
- 文中所有 access token 假設為業界最常用的 JWT 格式。若要用其他 token 格式,必須根據對應授權伺服器的檔說明操作。
MCP 驗證是怎樣運作?
根據最新的 MCP 驗證規範,MCP 驗證流程如下圖:
-
MCP Client 向 MCP 伺服器
https://github-tools.com
請求資源。由於用戶尚未登入,這個請求的 HTTP 授權 header 並無包含代表用戶的 access token。 -
MCP 伺服器收不到 MCP Client 請求中的 access token,會回傳一個 HTTP 401 錯誤(未授權)。這個錯誤回應內帶有 WWW-Authenticate header,其內含 MCP 伺服器資源 metadata 的 URL(
resource_metadata
欄位值)。 -
MCP Client 由 WWW-Authenticate header 抽取
resource_metadata
值(如:https://github-tools.com/.well-known/oauth-protected-resource
),並到此網址以資源伺服器身分請求該資源 metadata。metadata 會包括如authorization_servers
、scopes_supported
等內容,幫助 MCP Client 得知需從哪個授權伺服器領取有指定權限的 access token 才能存取 MCP 伺服器。
4-8. MCP Client 根據資源 metadata 中得到的授權伺服器 metadata URL 請求授權伺服器 metadata,之後同授權伺服器完成 OAuth 2.1 授權流程並獲得 access token。
-
MCP Client 夾帶來自授權伺服器的 access token 向 MCP 伺服器重新請求資源。
-
MCP 伺服器驗證 token 合法後回傳所請求的資源,之後 MCP Client 及 MCP 伺服器會持續以有效 token 進行通訊。
接下來會根據 MCP 驗證流程,逐步講解 MCP 伺服器驗證機制如何落實。
處理未授權請求:回傳 401 錯誤及 WWW-Authenticate Header
如上流程所示,當 MCP Client 未附帶 access token 請 求 MCP 伺服器時,伺服器需回傳 HTTP 401 Unauthorized 錯誤,並在 WWW-Authenticate
header 包含 MCP 伺服器資源 metadata 的網址。
根據 MCP 驗證規範的錯誤處理要求,除了 MCP Client 請求不帶 access token,當 MCP 伺服器收到的 access token 無效時,也應回傳 401 錯誤及 WWW-Authenticate
header。
知道什麼時候要返回 401 之後,下個問題是:WWW-Authenticate
header 應怎樣構建?
根據 RFC9728 第 5.1 節,WWW-Authenticate
header 需要帶上 resource_metadata
參數,表明被保護資源 metadata 的 URL。
其格式如下:
這裡,Bearer
為驗證方案,表示需要用 Bearer token 存取 OAuth 2.0 保護的資源(參見 MDN 說明)。resource_metadata
之值,是 MCP 伺服器提供資源 metadata 端點的完整網址。
實際程式碼實現例子如下:
MCP Client 收到這種 401 錯誤後,會根據 WWW-Authenticate
header 之 resource_metadata
值存取 MCP 伺服器的資源 metadata;然後依 metadata 提供資訊,再向指明的授權伺服器發起授權請求拿回一個可用於存取 MCP 伺服器的 access token。
現在你知道哪裡要回傳 401 錯誤且要如何帶住 resource_metadata
URL。不過「resource metadata URL 應怎麼建?metadata 有什麼內容?」會在下文繼續說明。
實現資源 metadata 發現機制
根據 MCP 驗證流程,MCP Client 收到 401 錯誤後,會即時向 MCP 伺服器請求資源 metadata。所以 MCP 伺服器作為資源伺服器,必須實現資源 metadata 發現機制。
決定 metadata 端點 URL 路徑
OAuth 系統用網址標識資源位址,此網址稱為「資源指標」。按 RFC9728 規定,資源 metadata 應放於專用 /.well-known
路徑之下。
若 MCP 伺服器(如 https://github-tools.com
)只供一項服務,metadata 端點應為:
如同一 hostname 提供多項獨立 MCP 服務,每項服務應設 單獨 metadata 端點。例如企業平台 https://api.acme-corp.com
提供:
https://api.acme-corp.com/github
- GitHub 整合https://api.acme-corp.com/slack
- Slack 整合https://api.acme-corp.com/database
- 資料庫查詢
則其 metadata 端點分別為:
https://api.acme-corp.com/.well-known/oauth-protected-resource/github
https://api.acme-corp.com/.well-known/oauth-protected-resource/slack
https://api.acme-corp.com/.well-known/oauth-protected-resource/database
這設計好處在於每個服務可設定不同權限範圍及授權伺服器,例如:
- GitHub 服務用 GitHub OAuth 伺服器,需
github:read
、github:write
權限 - Slack 服務用 Slack OAuth 伺服器,需
slack:channels:read
、slack:messages:write
權限 - 資料庫服務用企業內部授權伺服器,需
db:query
權限
總結,metadata 端點網址格式如下:
你可以按此方法,根據資源指標計算出 metadata 端點 URL:
構建資源 metadata 回應
決定了端點路徑後,此端點須回傳 RFC9728 規定的 JSON 格式 metadata。
實際需關注四個核心欄位。
resource
欄:資源指標,應跟 MCP Client 擬要存取的資源地址一致。authorization_servers
:陣列,指明 MCP Client 應向哪些授權伺服器請求 access token。根據 OAuth 2.0 Protected Resource Metadata(RFC 9728),此欄為 optional。但 MCP 驗證規範強制要求,因 Client 必須明確知悉向哪個授權伺服器發起授權流程。scopes_supported
:列舉此資源伺服器支援的所有權限範圍。bearer_methods_supported
:指本伺服器支援哪種方式接收 access token。大多設為["header"]
,即 MCP Client 應用 HTTP Authorization header 傳送 token。
舉例:欲為 https://github-tools.com
MCP 伺服器配置資源 metadata:
此配置告訴 MCP Client:你要存取的資源是 https://github-tools.com
,需向 https://auth.github-tools.com
申請 access token,可申請 github:read
、github:write
、repo:admin
權限,用戶端須以 HTTP Authorization header 夾帶 token。
大部分應用場景下設定好這四項即可,複雜情況可參考 RFC9728 完整欄位清單。
驗證 access token
MCP Client 向授權伺服器取回 access token 後,再把此 token 帶到 MCP 伺服器存取資源。
實踐中 MCP 伺服器驗證 access token 時,重點如下:
- 基於 MCP 伺服器配置驗證 token,不要直接用 token 內帶的授權伺服器資訊
- 要嚴格驗證 token 的 audience,確保該 token 真為本 MCP 伺服器資源而簽發
- 要正確處理權限(scope)校驗
應用 MCP Server 配置驗證 token
MCP 伺服器收到 access token 後,有些開發者會依靠 token 帶的 issuer
取相應授權伺服器資料驗證 token。特別當 MCP Server metadata 配置多個授權伺服器,如:
在這場景下,開發者或會直接從未驗證的 token 讀出 issuer
,再憑它到該授權伺服器驗證。攻擊者可製作惡意授權伺服器,簽發假 access token 給 MCP 伺服器。若你直接信任 token 之 issuer
指向惡意伺服器,token 驗證會被錯誤通過。
正確方法:
- 只配置一個授權伺服器時,直接依後台配置的授權伺服器做 token 驗證
- 多授權伺服器時,先從 token 取出
issuer
,僅於 MCP 伺服器配置裡尋到該 issuer 時才用其驗證此 token。找不到則直接拒絕所提交的 token
並且,在 token 驗證要嚴格校驗 issuer。
以 jose JWT library 範例:
驗證 token audience
根據 MCP 驗證規範 Token Audience Binding and Validation,當客戶端向授權伺服器請求 access token,必須聲明這個 token 要存取哪個資源伺服器。MCP 伺服器驗證 token 時亦必須檢查該 token audience 是否等同於自身。
此機制源自 Resource Indicators for OAuth 2.0(RFC 8707)。其流程如下:
-
請求階段:MCP Client 向授權伺服器請 token 時,會傳
resource
參數(如https://github-tools.com
),表明該 token 用來存取哪一個 MCP Server。 -
token 發放階段:授權伺服器收到請求後,會把該資源地址綁定到 access token 上。若採 JWT,會把它寫到 JWT payload 裡
audience
(即aud
)欄位。 -
token 驗證階段:MCP 伺服器驗證 access token 時,必須嚴格比對 JWT 內的
audience
跟本身資源指數是否完全相符。
以 https://github-tools.com
MCP Server 為例:
audience 驗證是防止 token 被濫用的關鍵安全機制。否則攻擊者可用針對其他服務簽發的 access token 嘗試假冒用戶存取你的 MCP 伺服器。若未驗證 audience,就有可能意外接受本不應該被接受的 token。
權限(scope)校驗
不少 MCP 伺服器管理內部資源的存取權,因不同用戶權限範圍可不同。
所以 access token 驗證通過後,還要檢查其是否具備當前操作所需權限。可透過檢查 token 內的 scope
欄位是否覆蓋當前資源要求權限:
注意,根據 MCP 驗證規範,如 token 權限不足以存取指定資源,應回傳 403 Forbidden。
結語
經本文介紹,你已能為 MCP 伺服器實現符合最新規範的驗證功能。記住幾個關鍵:安全驗證 token、正確配置 metadata、嚴格檢查 audience。
如果你正開發 MCP 伺服器,不妨試用 MCP Auth 庫。它已內建本文討論的所有功能,能助你快速整合驗證。
有疑問歡迎在 GitHub 討論。我們一齊推動 MCP 生態!