跳到主要内容

保护 MCP 服务器:OAuth、受众绑定与混淆代理

高级
What you'll learn
  • 理解为什么一个远程(HTTP)MCP 服务器是一个 OAuth 2.1 资源服务器,而不仅仅是一个 API 密钥端点
  • 追踪发现握手过程:401 → Protected Resource Metadata → Authorization Server Metadata → 令牌
  • 解释令牌受众绑定(RFC 8707)以及它为什么能阻止一个服务的令牌在另一个服务上生效
  • 指出混淆代理陷阱以及封堵它的那一条规则:绝不将客户端的令牌透传给上游 API
  • 在把 MCP 服务器暴露到互联网之前,应用一份简短的加固检查清单

MCP 已经从新鲜事物变成了智能体触达工具的默认方式——这意味着 MCP 服务器如今正守在真实数据和真实操作的前面。你通过 STDIO 启动的本地服务器信任它所处的环境:它从环境变量读取凭据,并且没有需要防御的网络边界。而一旦你把同一个服务器变成远程(HTTP),任何能访问到该 URL 的人都可以尝试调用它。这就把它变成了一个授权问题,而 MCP 规范用 OAuth 2.1 来回应——而不是一套定制的 API 密钥方案。

本页讨论的是远程场景。如果你的服务器只用 STDIO,规范明确表示不要走 OAuth 流程——从环境中获取凭据然后继续即可。

三种角色

OAuth 把问题拆分给三方。MCP 干净地映射到它们之上:

谁是 MCP OAuth 流程中的谁
按 Enter 或空格键翻转卡片。使用左右方向键在卡片之间切换。已显示术语。
1 / 3

关键的思维转变:MCP 服务器自己从不处理登录。 它只验证别人签发的令牌。正是这种分离让你能在一个自己编写的服务器前面放上一个现成的身份提供方。

发现握手

客户端不应当需要预先配置好在哪里进行认证。MCP 让发现过程自动化,由一个 401 驱动:

Guided walkthrough1 of 6
  1. 第一个请求裸奔发出。服务器以 HTTP 401 Unauthorized 拒绝它,并附带一个指向其资源元数据 URL 的 WWW-Authenticate 头。

注意客户端一侧没有任何硬编码的认证配置——是那个 401 引导了一切。这正是重点所在:智能体可以连接到一个它从未见过的服务器,并弄清楚该如何认证。

受众绑定:那条承重的规则

下面就是受众绑定要防范的失效模式。假设某个用户持有一个为 calendar.example.com 签发的令牌。位于 evil.example.com 的一个恶意(或只是马虎)的 MCP 服务器诱使客户端把那个令牌发给它。如果 evil 接受了它,它现在就可以转身以该用户的身份去调用日历 API。一个服务的令牌在另一个服务上生效了。OAuth 的安全边界就此崩塌。

修复办法是 Resource Indicators(RFC 8707)

Guided walkthrough1 of 3
  1. 在授权请求和令牌请求中,客户端都必须包含一个 resource 参数,设置为它打算调用的 MCP 服务器的规范 URI——例如 resource=https://mcp.example.com。即便不确定 AS 是否支持,它也会发送这个参数。

授权请求上的 resource 参数(URL 编码)

&resource=https%3A%2F%2Fmcp.example.com

规范 URI 有严格要求:https://mcp.example.comhttps://mcp.example.com:8443/mcp 是有效的;mcp.example.com(无 scheme)和 https://mcp.example.com#frag(带 fragment)则无效。为了互操作性,优先使用不带末尾斜杠的形式。

混淆代理:绝不透传令牌

这是把一个善意的 MCP 服务器变成攻击者代理的错误。它就是智能体安全中那个同样的混淆代理问题,被磨成了一条具体的规则。

MCP 服务器常常需要调用上游 API(GitHub、某个数据库服务、另一个 SaaS)。诱惑在于:把客户端交给你的令牌拿去转发到上游。不要这么做。 规范说得很直白:MCP 服务器绝不能透传它从客户端收到的令牌。

为什么危险:客户端的令牌是以你的服务器为受众签发的。如果你转发它,上游 API 可能会像它来自你一样信任它,或者假设你已经验证过它——于是一个仅限一跳的令牌就在两跳之外做起了工作,游离于任何人的同意模型之外。

Watch out
  • 如果你的 MCP 服务器要调用上游 API,它就是作为一个独立的 OAuth 客户端去访问那个 API,并从上游的授权服务器获取它自己的令牌。两个独立的令牌,两个独立的受众。客户端的令牌止步于你的门口。

一份起飞前的加固检查清单

在远程 MCP 服务器接触公共互联网之前:

Guided walkthrough1 of 7
  1. 所有 AS 端点都必须使用 HTTPS。重定向 URI 必须是 HTTPS 或 localhost——别无其他。

自我检查

自我检查

0/4
  1. 一个远程 MCP 服务器收到了一个不带访问令牌的请求。规范要求它首先做什么?
  2. 令牌受众绑定(RFC 8707)在防范什么?
  3. 你的 MCP 服务器需要调用上游的 GitHub API。它应当如何处理客户端发给它的访问令牌?
  4. 对于一个 STDIO(本地)MCP 服务器,规范说凭据应当如何处理?

来源与延伸阅读