XBSTACK Tech Image - XBSTACK

MCP OAuth 认证实战:远程 MCP Server 为什么不能裸奔?

Release Date
2026-06-09
Reading Time
6分钟
Impact Factor
3,521
MCP 协议
oauth
authorization
remote-mcp
mcp-server
tool-scope
ai-agent-security
Xiaobai's Note / 实验室笔记

这篇文章记录了我在贵阳实验室的实战过程。我坚信,在技术下行的时代,程序员唯一的护城河就是通过 AI 建立属于自己的数字资产。

本文解决的问题

  • 远程 MCP Server 为什么不能直接暴露公网?
  • MCP Authorization 和普通 API Key 有什么区别?
  • Protected Resource Metadata 是什么?
  • MCP Server 如何发现 Authorization Server?
  • Bearer Token、Scope、Resource Indicators 在 MCP 里怎么用?
  • 如何避免不同用户调用到同一组高危 Tools?

适合谁读

  • 已经把 MCP Server 从 stdio 迁移到 Streamable HTTP 的开发者
  • 想把 MCP Server 部署到 VPS、Cloudflare Tunnel、企业内网的人
  • 正在设计 Claude / Cursor 远程工具调用权限的人
  • 关心 MCP OAuth、Token、Scope、Tool 权限边界的全栈开发者

一、本地 MCP 和远程 MCP 的安全边界完全不同

本地 MCP Server 的默认信任来自本机环境,远程 MCP Server 的默认假设必须是“不信任任何请求”。

在本地 stdio 模式下,Claude 或 Cursor 直接作为父进程启动 MCP Server,安全边界由操作系统内核保护。除非你的电脑本身被黑,否则没人能绕过客户端调用你的工具。

但当你把 MCP Server 迁移到远程(通过 HTTP/SSE 传输)后,情况发生了质变: Claude / Cursor → 网络 → 网关 / 代理 → MCP Server → 文件 / 数据库 / API

一旦接入公网或团队内网,你的 MCP Server 就面临以下核心风险:

  • 未认证访问:任何知道你 URL 的人都能调用你的 Tools。
  • Token 泄露:如果只用简单的 API Key,泄露后权限难以精细化撤销。
  • 越权调用:用户 A 可能会诱导 AI 调用本属于用户 B 的资源工具。
  • 注入攻击:LLM 可能被 Prompt Injection 诱导,在未授权的情况下执行高危 Tool。

二、MCP Authorization 到底解决什么?

MCP Authorization 解决的不是“模型能不能调用工具”,而是“哪个 Client 可以代表哪个用户调用哪些受限工具”。

根据官方 MCP 规范草案,MCP 在 transport 层提供了 authorization 能力。这意味着认证和授权逻辑应当在建立连接和发起请求时执行。

我们需要区分三个层面的安全:

  • Authentication (认证):验证“你是谁”(通常是 MCP Client 或背后的用户)。
  • Authorization (授权):验证“你能调用什么”(即 Token 携带的 Scope)。
  • Tool Scope (工具边界):在 MCP Server 内部,根据身份决定暴露哪些具体的 Tools 列表。

三、Protected Resource Metadata 是什么?

Protected Resource Metadata 可以理解为:MCP Server 告诉 Client,“如果你要访问我,应该去哪里拿授权”。

MCP Server 不应该让 Client 盲目猜测授权方式。规范要求 MCP Server 实现 OAuth 2.0 Protected Resource Metadata 机制,用于声明受保护资源的相关信息,特别是它所信任的授权服务器 (Authorization Servers) 列表。

这确保了 MCP 生态的互操作性:一个标准的 MCP Client (如 Claude 桌面端或某个自定义 Agent) 发现一个远程 Server 时,可以通过读取 metadata 自动引导用户完成 OAuth 流程。


四、Authorization Server Discovery 怎么走?

远程 MCP Server 应该通过标准 discovery 机制告诉 Client 授权入口,而不是把 token endpoint 写死在文档里。

目前推荐两种发现路径:

  1. 「401 Unauthorized 挑战」:当 Client 发起无 Token 请求时,Server 返回 401,并在 WWW-Authenticate 头部包含 protected_resource_metadata 的 URI。
  2. 「Well-known 路径」:在 Server 的 .well-known/oauth-protected-resource 路径下直接提供 JSON 配置。

这种机制让远程 MCP Server 具备了“即插即用”的生产级安全性。


五、最小远程 MCP 认证架构

为了实现安全的远程调用,一个典型的架构如下:

Claude / Cursor (Client) ↓ 携带 Access Token 发起 HTTP 请求 ↓ 远程 MCP Server (Resource Server) ↓

  1. 校验 Token 有效性
  2. 校验 Scope (是否包含 tool:call 权限)
  3. 校验 Resource Indicator (Token 是否签发给本服务器) ↓ Tool 层逻辑校验 (根据 User ID 隔离环境) ↓ 执行具体工具并返回结果

六、为什么 API Key 不够?

API Key 适合个人实验,不适合多用户、远程、可撤销、可审计的 MCP 服务。

在生产环境下,API Key 存在显著弊端:

  • 无法表达用户身份:Key 通常是静态的,难以区分是哪个终端用户在调用。
  • 难以细分 Tool Scope:你很难为一个 API Key 设置“只能调用只读工具”的动态权限。
  • 泄露风险:API Key 一旦泄露,除非更换整个 Key,否则无法针对特定 session 撤销。
  • 审计粒度:OAuth Token 可以绑定更丰富的元数据,方便在日志中追踪具体的调用链路。

七、Tool Scope 怎么设计?

远程 MCP Server 不能只验证“用户是否登录”,还要验证“用户能不能调用这个 Tool”。

我们应该在代码中实现基于 Scope 的工具暴露逻辑。例如:

  • read:files: 仅允许调用 list_directoryread_file
  • write:files: 允许调用 write_filedelete_file
  • admin:db: 允许执行 drop_table 等高危操作。

在 MCP Server 的 listTools 处理器中,你应该根据请求上下文中的身份信息,动态返回当前用户有权使用的工具子集,而不是一把抓地全部暴露。


八、Resource Indicators:Token 不能到处用

远程 MCP Server 的 Token 不应该在多个服务之间随意复用。

根据 MCP 规范对 OAuth 2.1 的引用,客户端在请求授权和获取 Token 时,应该包含 resource 参数(Resource Indicators)。这意味着授权服务器签发的 Token 是带有“受众”标记的。

一个签发给 https://api.xbstack.com/mcp 的 Token,如果不包含对 https://internal.tools.local/mcp 的授权,那么后者应该拒绝该请求。这有效防止了 Token 被中间人拦截后用于攻击其他敏感的 MCP 服务。


九、常见报错与常见坑 (Error Logs)

1. Error: HTTP 401 Unauthorized

现象:Client 无法连接远程 Server。 原因:通常是 Token 缺失、过期,或者 Server 要求的 WWW-Authenticate 挑战格式不符合 Client 预期。

2. Error: Insufficient Scope

现象:连接成功,但 listTools 返回空列表,或调用特定工具时报错。 原因:Token 权限不足。请检查 OAuth 授权时申请的 scopes 是否覆盖了所需的 Tool 权限。

3. 风险:多租户会话泄露

陷阱:Server 在内存中缓存了 Tool 状态,导致用户 A 的上下文干扰了用户 B。 对策:远程 MCP Server 必须是无状态的,或者必须根据 Token 中的 User ID 进行严格的会话隔离。


十、实战建议:远程 MCP Server 的安全底线

最新的安全研究显示,目前公网上暴露的远程 MCP Server 中,有超过 40% 处于完全未认证状态。这在 AI 时代是非常危险的,因为 LLM 可能被诱导执行非预期的破坏性操作。

我建议你的远程 MCP Server 至少做到:

  • 强制 HTTPS 传输,禁止明文 HTTP。
  • 使用 Bearer Token 校验,哪怕初期只是静态 Token 验证(作为过渡)。
  • 实现 Tool 级别的权限校验逻辑。
  • 开启详细的审计日志,记录每个 Tool 被谁调用、输入参数是什么。

FAQ

MCP Server 一定要用 OAuth 吗?

本地 stdio Server 不一定需要;远程 MCP Server 如果涉及用户资源、私有数据、企业工具或生产系统,就应该使用 OAuth 或等价的认证授权机制。

API Key 可以替代 OAuth 吗?

个人实验可以,但多用户、可撤销、可审计的远程服务不建议只用 API Key。

MCP Authorization 和 Tool Scope 是一回事吗?

不是。Authorization 解决“谁可以访问 MCP Server”,Tool Scope 解决“这个用户可以调用哪些工具”。

远程 MCP Server 能不能只靠 Cloudflare Access?

可以作为第一层网络与身份边界,但 MCP Server 内部仍然要做 Tool Scope 和资源权限判断。

为什么要校验 resource / audience?

为了防止一个 Token 被拿去访问本不该访问的 MCP Server。


继续阅读

喜欢这篇文章?
加入小白实验室的周刊

每周我都会分享最新的 AI 实战、产品构建心得以及程序员视角的投资笔记。不发废话,只发干货。已有 5000+ 开发者在此共同进化。

Comments