MCP 伺服器認證實作指南:使用最新規範
提供 MCP 伺服器要符合 2025-06-18 規範的關鍵認證實作重點。
幾天前(2025 年 6 月 18 日),MCP(Model Context Protocol)團隊釋出了最新版的 MCP 規範 (2025-06-18)。這次更新針對認證規範有一個關鍵改動。MCP 伺服器不再作為 授權伺服器 發放 Access Token,而是改為消耗 access token,並作為 資源伺服器 提供資源。
身為 MCP Auth(一個 plug-and-play 的 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 伺服器開發者一般無需也無法干預。細節可參考 OAuth Client 和 授權伺服器
- 文章中所有提到的 access token 都假設是 JWT 格式,這也是市面上最常見的格式。若是其他格式,請依照對應授權伺服器發行商所提供的文件處理。
MCP 認證運作方式
根據最新版的 MCP 認證規範,MCP 認證流程如下圖所示:
-
MCP Client 會向 MCP 伺服器(如
https://github-tools.com
)請求資源。由於使用者尚未登入,這個請求的 HTTP 授權標頭內不會帶有代表該用戶身分的 access token。 -
MCP 伺服器從請求中取得不到 access token,便回傳 HTTP 401 錯誤給 MCP Client。這個錯誤響應內會包含 WWW-Authenticate 標頭,該標頭裡附帶 MCP 伺服器資源中繼資料(
resource_metadata
欄位的值)網址。 -
MCP Client 從收到的 WWW-Authenticate 標頭中解析出
resource_metadata
欄位的網址(如:https://github-tools.com/.well-known/oauth-protected-resource
),然後以 MCP 伺服器資源伺服器角色向這個網址請求資源中繼資料。這個資訊會包含例如authorization_servers
、scopes_supported
等內容,協助 MCP Client 理解要去哪個授權伺服器取得符合權限需求的 access token。
4-8. MCP Client 根據資源中繼資料裡的授權伺服器 metadata URL 再去取得授權伺服器 metadata,然後同授權伺服器進行 OAuth 2.1 認證授權流程並取得 access token。
-
MCP Client 攜帶剛才取得的 access token,再次向 MCP 伺服器請求資源。
-
MCP 伺服器驗證 token 合法後回應請求。之後 MCP Client 與 MCP 伺服器之間就會以這個有效 token 持續通訊。
下面將一步一步根據 MCP 認證流程詳述 MCP 伺服器端的實作方法。
處理未授權請求:回傳 401 與 WWW-Authenticate 標頭
如上流程所示,當 MCP Client 沒有帶 access token 請求 MCP 伺服器時,MCP 伺服器應該回傳 HTTP 401 Unauthorized 錯誤,並帶上一個 WWW-Authenticate
標頭,其中要包含 MCP 伺服器資源中繼資料的網址。
根據 MCP 認證規範錯誤處理 要求,除了 MCP Client 沒帶 access token 的請求,若 MCP 伺服器收到非法 access token,同樣也要回傳帶 WWW-Authenticate
標頭的 401 錯誤。
知道哪些情況下要返回 401 後,要怎麼構造回應裡的 WWW-Authenticate
標頭?
依照 RFC9728 Section 5.1 要求,WWW-Authenticate
標頭中要用 resource_metadata
這個參數,註明 Protected Resource Metadata 的網址。
基本格式如下:
這裡的 Bearer
是驗證協定名,表示需要用 bearer token 存取 OAuth 2.0 保護的資源(請參閱 MDN 文件 )。後面的 resource_metadata
參數值就是你 MCP 伺服器對外提供的資源中繼資料端點完整 URL。
實際程式碼範例如下:
MCP Client 收到這種 401 錯誤後,會從 WWW-Authenticate
標頭裡的 resource_metadata
欄位值取得 MCP 伺服器資源中繼資料,依據這些資訊再去指定的授權伺服器申請 access token。
現在我們已經知道什麼時候要丟 401 錯誤,也知道要帶上 resource_metadata 的 URL。剩下的問題是——這個資源中繼資料到底怎麼去實作它的 endpoint 路徑,內容該塞什麼?這就是下一段要說明的主題。
實作資源中繼資料發現機制
根據 MCP 認證流程,MCP Client 收到 401 錯誤後會立即去要 MCP 伺服器的資源中繼資料,所以 MCP 伺服器需作為 Resource Server 支援資源中繼資料發現機制。
確定位址 endpoint 的路徑
在 OAuth 系統裡,我們通常用網址來標識資源位址,這稱為「資源指示器(resource indicator)」。RFC9728 規定,資源中繼資料必須掛載在一個特定的 /.well-known
路徑下。
如果你的 MCP 伺服器(如 https://github-tools.com
)只有單一服務,則 metadata endpoint 建議設成:
如果你的同一主機下有多個不同 MCP 服務,每一個要有獨立的中繼資料 endpoint。例如企業平台 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
- Database 查詢服務
對應 metadata endpoint 分別是:
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
這樣設計的好處是每個服務可以有獨立的權限範圍(scope)及授權伺服器設定,例如:
- GitHub 服務對接 GitHub 授權伺服器,需要
github:read
、github:write
權限 - Slack 服務對接 Slack 授權伺服器,需要
slack:channels:read
、slack:messages:write
權限 - Database 走企業內部授權伺服器,需要
db:query
權限
總結以上,資源中繼資料 endpoint URL 遵循此規則:
可以根據 resource indicator 算出中繼資料 endpoint:
建立資源中繼資料的回應內容
確定 path 後,要讓這個 endpoint 回傳符合 RFC9728 的 JSON 格式 metadata。
實作時主要聚焦四個核心欄位:
第一是 resource
,即資源指示器,要與 MCP Client 欲存取的資源網址一致。
第二是 authorization_servers
,一個陣列,列出 MCP Client 應該到哪些授權伺服器申請 access token。根據 OAuth 2.0 Protected Resource Metadata(RFC 9728),這是選填的,但 MCP 認證規範下這欄必填,否則 MCP Client 無法得知去哪裡授權。
接下來的 scopes_supported
,羅列此 Resource Server 支援的權限範圍。
bearer_methods_supported
則會告訴 MCP Client 該伺服器支援哪些方式收 token。一般我們設為 ["header"]
,即要求 MCP Client 向 HTTP Authorization header 放上 access token。
具體範例如下,假設你要對 https://github-tools.com
這台 MCP 伺服器設定資源中繼資料:
這個設定告訴 MCP Client:你要存取 https://github-tools.com
,要向 https://auth.github-tools.com
申請 token,token 權限 scope 可以有 github:read
、github:write
、repo:admin
,且 token 應以 HTTP Authorization header 帶出。
大部分場景下,配置這四個欄位即可讓 MCP Client 正常使用。如需進階配置可參閱 RFC9728 的完整欄位文件。
驗證 access token
取得 access token 後,MCP Client 即會攜帶 token 請求 MCP 伺服器。
MCP 伺服器驗證 access token 時務必注意幾點:
- 執行基本 token 驗證時,必須根據 MCP 伺服器本身設定驗證,而非只拿 token 裡帶的授權伺服器(issuer)資料。
- 要驗證 token 的 audience 是否等於該 MCP 伺服器,避免 token 被誤用到非授權資源。
- 正確執行 scope 的驗證。
用 MCP 伺服器設定驗證 access token
有些人拿到 token 會直接根據 token 的 issuer
去找對應授權伺服器,而當 MCP 伺服器設定了多個授權伺服器,比如資源中繼資料如下:
開發者常直接提取未驗證 token 的 issuer
作為後續驗證依據,但這很危險。攻擊者可以偽造一個惡意授權伺服器,產生簽名正確但不具有實權的 access token。如果 MCP 伺服器沒有在後端明確設定授權伺服器清單、而是完全信任 token 的 issuer
,就會驗證通過這種假的 token。
正確做法應該是:
- 僅有一個授權伺服器:後端設定定死驗證邏輯。
- 多個授權伺服器:從未驗證的 token 解析出
issuer
,然後比對是否存在於 MCP 伺服器自己設定好的授權伺服器列表。找得到才用這個 server 的 JWK 驗證,找不到直接拒絕該 token。
而且記得驗證 token 的 issuer 要嚴格。
假設採用 jose JWT 函式庫驗證,可以這樣寫:
audience 驗證
根據 Token Audience Binding and Validation 條文,MCP Client 向授權伺服器請求 access token 時必須標示這個 token 要用來授權哪些資源,MCP 伺服器驗證時也必須判斷 token 裡的 audience 是否與自己的資源指示器相符。
這類機制來自 Resource Indicators for OAuth 2.0(RFC 8707)。具體三階段流程如下:
- Client 提 token 時,請求參數裡標明
resource
欄位,如https://github-tools.com
- 授權伺服器發 token 會把 resource 寫入 JWT payload 的
audience
(aud),標註這個 token 專門給誰用 - MCP 伺服器接到 token 時,需要檢查 JWT 的
aud
是否等於自己的資源 identifier
以 https://github-tools.com
為例:
audience 驗證是防止 token 被濫用的關鍵安全機制。若不驗證,攻擊者可拿本不應該可用於你服務的 token 嘗試調用你伺服器 API,若你沒驗證就會錯誤放行。
權限範圍 scope 驗證
有些 MCP 伺服器需要對內部資源控管權限,不同使用者會有不同權限範圍。
token 驗證通過後,應進一步確認該 access token 是否具備所要求的權限。直接比對 token 的 scope 欄位是否括有存取當前資源所需權限。
根據 MCP 認證規範,若 token 權限不夠,應回傳 403 Forbidden。
小結
本文介紹之後,你應該會實作出一個符合最新規範的 MCP 伺服器認證機制。記得幾個重要原則:token 驗證要確實安全、metadata 設定要正確、audience 驗證一定要做。
如果你正在開發 MCP 伺服器,非常推薦直接使用 MCP Auth 函式庫,它已經內建本文涉及的所有實作細節,能幫你快速導入完整 auth support。
有任何問題歡迎上 GitHub 討論,一起讓 MCP 生態更完善!