繁體中文(香港)
  • mcp
  • mcp-auth
  • oauth

深入評審 MCP 授權規範(2025-03-26 版)

深入分析 MCP 授權規範,檢視 MCP 伺服器在作為授權及資源伺服器時的雙重角色、動態客戶端註冊機制,以及在實際場景中實施此協議的考量。

Yijun
Yijun
Developer

Stop wasting weeks on user auth
Launch secure apps faster with Logto. Integrate user auth in minutes, and focus on your core product.
Get started
Product screenshot

MCP(模型上下文協議)是一個開放標準,允許 AI 模型與外部工具和服務互動。它被行業廣泛採用。由於 MCP 支持基於 HTTP 的傳輸方式,遠程 MCP 伺服器將在 MCP 生態系統中扮演愈加重要的角色。

與允許每個用戶運行自己伺服器實例的本地 MCP 伺服器不同,遠程 MCP 伺服器要求所有用戶共享相同的 MCP 伺服器服務。這提出了 MCP 授權規範旨在解決的核心問題:如何允許 MCP 伺服器代表用戶訪問用戶資源

本文將深入分析 MCP 授權規範。這將幫助你理解 MCP 授權規範的設計原則及一些實施 MCP 授權的方向。由於此規範仍在演進中,我將分享一些基於我個人實施 Authenticator 經驗的想法,包括:

  • 作為授權框架的 OAuth 2.1 的優勢和限制
  • MCP 伺服器作為授權伺服器及資源伺服器的雙重角色挑戰
  • 實施完整授權伺服器的實際複雜性
  • 適合委派第三方授權的場景分析
  • 動態客戶端註冊的實際權衡
  • 清晰定義 MCP 伺服器資源界限的重要性

MCP 授權規範概述

MCP 授權規範定義了 MCP 伺服器(遠程)與 MCP 客戶端之間的身份驗證過程。

我認為基於 OAuth 2.1 制定此規範是一個非常合理的選擇。作為授權協議框架的 OAuth 解決了如何允許用戶授權第三方應用代表它們訪問用戶資源的問題。如果你不熟悉 OAuth,可以查看 AuthWiki-OAuth 獲得更多信息。

在 MCP 客戶端與 MCP 伺服器的場景中,這是關乎於 "用戶授權 MCP 客戶端訪問 MCP 伺服器上的用戶資源"。目前,"MCP 伺服器上的用戶資源" 主要是指 MCP 伺服器提供的工具或是 MCP 伺服器後台服務提供的資源。

為了實施 OAuth 2.1 認證過程,協議要求 MCP 伺服器提供以下介面來與 MCP 客戶端合作完成 OAuth 2.1 認證過程:

  • /.well-known/oauth-authorization-server:OAuth 伺服器元數據
  • /authorize:授權端點,用於授權請求
  • /token:令牌端點,用於令牌交換和刷新
  • /register:客戶端註冊端點,用於動態客戶端註冊

認證過程如下:

該規範還規定了 MCP 伺服器如何通過第三方授權伺服器來支持授權委派。

規範中的流程示例如下(取自規範內容):

在此場景中,雖然 MCP 伺服器將授權委派給第三方授權伺服器,但 MCP 伺服器仍然作為 MCP 客戶端的授權伺服器。這是因為 MCP 伺服器需要向 MCP 客戶端簽發自己的訪問令牌。

在我看來,這個場景似乎更適合處理 MCP 伺服器代理 MCP 客戶端(用戶)訪問第三方資源(例如 Github 資源庫)的情況,而不是 MCP 伺服器代理 MCP 客戶端(用戶)訪問 MCP 伺服器自己的資源。

總結來說,根據協議,MCP 伺服器在 OAuth 中同時擔任授權伺服器和資源伺服器的角色。

接下來讓我們討論 MCP 伺服器作為授權伺服器與資源伺服器的職責。

MCP 伺服器作為授權服務

當 MCP 伺服器作為授權伺服器時,這意味著 MCP 客戶端的終端用戶在 MCP 伺服器上有自己的身份。MCP 伺服器負責驗證該終端用戶,並向這位終端用戶簽發訪問 MCP 伺服器資源的令牌。

如上所述,MCP 授權規範中所需的授權相關介面意味著 MCP 伺服器必須提供一個授權伺服器的實現。

然而,在 MCP 伺服器上實施授權伺服器功能對於開發者來說是一個重大的挑戰。一方面,大多數開發者可能不熟悉 OAuth 相關概念。另一方面,在實施授權伺服器時有許多細節需要考量。如果開發者不來自相關領域,可能在實施中引入像是安全問題等。

但是,協議本身並不限制 MCP 伺服器只能自己實施授權伺服器功能。開發者完全可以將這些授權相關端點重定向或代理到其他授權伺服器上。對 MCP 客戶端來說,這與 MCP 伺服器自己實施授權伺服器功能沒有區別。

你可能會疑惑,這種方法是否應該使用上述提到的第三方授權委派方法?

從我的觀點來看,這主要取決於你依賴的第三方授權服務的用戶是否與 MCP 伺服器的終端用戶相同。這意味著第三方授權服務簽發給你的訪問令牌將直接由你的 MCP 伺服器消耗。

  • 如果是,那麼你可以將 MCP 伺服器中的授權相關介面完全轉發到第三方授權服務。

  • 如果不是,那麼你應該使用規範中規定的第三方授權委派方法。你需要在 MCP 伺服器中維護 MCP 伺服器自己簽發的訪問令牌與第三方授權服務簽發的訪問令牌的映射關係。

我認為協議中規定的第三方授權委派方法在實際應用場景中略顯含糊。協議似乎是讓第三方來幫助 MCP 伺服器完成授權過程,但仍要求 MCP 伺服器簽發自己的訪問令牌。這實際上意味著 MCP 伺服器仍承擔作為授權伺服器發放訪問令牌的責任,這對於開發者來說並不更方便。我認為這可能是因為協議的作者考慮到直接將第三方訪問令牌返回給 MCP 客戶端會帶來一些安全問題(如洩露/濫用等)。

從我的經驗來看,協議中規定的第三方授權委派方法最適合的場景應該是 "用戶授權 MCP 伺服器訪問第三方資源" 的場景。例如,一個 MCP 伺服器需要訪問用戶的 Github Repo 並將 Repo 的代碼部署到代碼部署平台。在這種情況下,該用戶需要授權 MCP 伺服器訪問其 Github Repo 和訪問代碼部署平台。

在此場景中,由於終端用戶在 MCP 伺服器上有自己的身份,MCP 伺服器是 MCP 客戶端的授權伺服器。而對於第三方資源(在這種情況下是 Github),MCP 伺服器是一個第三方客戶端,它需要獲得用戶授權以訪問用戶在 Github 上的資源。在 MCP 客戶端與 MCP 伺服器之間,以及 MCP 伺服器與第三方資源之間,用戶身份是分離的。這使得在 MCP 伺服器中維護 MCP 伺服器自己簽發的訪問令牌與第三方授權服務簽發的訪問令牌之間的映射關係變得有意義。

所以協議中的第三方授權委派協議應該解決 "用戶授權 MCP 伺服器訪問第三方資源伺服器上的用戶資源" 的問題。

MCP 伺服器作為資源伺服器

當 MCP 伺服器作為資源伺服器時,MCP 伺服器需要驗證 MCP 客戶端的請求是否攜帶了有效的訪問令牌。MCP 伺服器將根據訪問令牌的範疇決定是否允許 MCP 客戶端訪問特定資源。

根據 MCP 的定義,MCP 伺服器提供的資源應該是 MCP 客戶端使用的工具。在這種情境下,MCP 伺服器只需要決定是否提供用戶訪問某些工具的權限。

但在實際場景中,MCP 伺服器提供的這些工具也需要與 MCP 伺服器的服務提供商自己的資源伺服器交互。此時,MCP 伺服器從客戶端請求中獲得的訪問令牌需要被用來訪問其自己的資源伺服器。在大多數情況下,MCP 伺服器和工具後台的資源伺服器是同一開發者。MCP 伺服器只是為 MCP 客戶端提供自己後台資源的介面。在這個情況下,MCP 伺服器可以與後台資源共用同一個授權伺服器簽發的訪問令牌。

在這種情況下,與其說 MCP 伺服器是一個資源伺服器,提供工具和其自身服務的資源,不如說現有的資源伺服器通過提供工具供 MCP 客戶端調用而成為 MCP 伺服器。

將其自身資源伺服器提供的資源納入 MCP 伺服器提供的資源,更多是出於實際場景的考量。但我個人仍然更偏好 MCP 伺服器只提供 MCP 客戶端使用的工具,而工具所依賴的資源應該是由 MCP 伺服器從其他資源伺服器(包括第一方與第三方)獲得的資源。這樣可以涵蓋所有的實際場景。

MCP 授權如何運作

在了解 MCP 伺服器作為授權伺服器和資源伺服器的職責後,我們可以知道 MCP 授權具體如何運作:

動態客戶端註冊

該規範還定義了授權伺服器如何識別客戶端。OAuth 2.1 提供動態客戶端註冊協議,允許 MCP 客戶端自動獲取 OAuth 客戶端 ID 而無需手動用戶介入。

根據規範,MCP 伺服器應支持 OAuth 2.0 的動態客戶端註冊協議。這樣,MCP 客戶端就可以自動註冊到新伺服器,獲得 OAuth 客戶端 ID。在 MCP 場景中建議使用這種方式主要因為:

  • MCP 客戶端無法提前知道所有可能的伺服器
  • 手動註冊會給用戶帶來麻煩
  • 可以無縫連接新的伺服器
  • 伺服器可以實施其自己的註冊策略

然而,從實踐的角度來看,我對於動態客戶端註冊在 MCP 場景中的應用有一些想法:

  • 在實際 OAuth 服務的實踐中,客戶端通常是一對一對應於特定業務應用。動態創建客戶端可能不利於在 OAuth 服務中有效管理相關資源(用戶、應用等)。OAuth 服務提供者通常希望對連接的客戶端有清晰的控制,而不是讓任何客戶端隨意註冊為客戶端。
  • 許多 OAuth 服務不推薦或不允許用戶動態創建客戶端,因為這可能導致服務濫用。大多數成熟的 OAuth 服務提供者(如 GitHub、Google 等)要求開發者通過他們的開發者控制台手動註冊客戶端,並可能還需要提供應用的詳細信息、回調 URL 等。
  • 手動註冊 OAuth 客戶端實際上是在開發過程中的一次性工作,而非每個終端用戶都需要執行的操作。這不會對開發者造成大的負擔。
  • 對於公共客戶端(例如原生應用、單頁應用等),我們有更安全的方法來實施 OAuth 流程,無需動態註冊。客戶端 ID 結合 PKCE(Proof Key for Code Exchange)可以為公共客戶端提供足夠安全的 OAuth 流程,而無需動態創建客戶端。
  • 雖然協議指出,使用動態客戶端註冊可以避免客戶端需要提前知道客戶端 ID,但實際上 MCP 客戶端始終需要提前知道遠程 MCP 伺服器的地址。如果是這樣,指定客戶端 ID 的同時傳入遠程 MCP 伺服器地址不會帶來太多額外麻煩。或者,我們也可以製定一個規則讓 MCP 客戶端詢問 MCP 伺服器的客戶端 ID,這不是一項困難的任務。

儘管動態客戶端註冊在理論上為 MCP 生態系統提供了靈活性,在實際實施中,我們可能需要考量是否真的需要這個動態註冊機制。對於大多數服務提供者來說,手動創建和管理 OAuth 客戶端可能是一種更可控且安全的方式。

總結

本文深入分析了 MCP 授權規範的設計理念和實施挑戰。作為基於 OAuth 2.1 的授權框架,此規範旨在解決遠程 MCP 伺服器如何代表用戶訪問用戶資源的關鍵問題。

通過詳盡討論 MCP 伺服器作為授權伺服器和資源伺服器的雙重角色,以及動態客戶端註冊和第三方授權委派等機制的利弊,本文提供了個人在實施 Authenticator 中的經驗反思與建議。

值得注意的是,MCP 授權規範仍在演變中。作為 Logto 團隊的一員,我們將持續關注此規範的最新進展,並在實踐中不斷優化我們的實施方案,以促進 AI 模型與外部服務之間的安全互動。