MCP 身份验证负责识别客户端及其代表的用户,授权则决定它们可以访问哪些工具、租户、资源和操作。对于远程 HTTP 服务器,当前 MCP 规范使用 OAuth 发现、PKCE、资源指示符、bearer token 和 audience 校验。后端仍需对最终资源执行授权。
本地 stdio 服务器使用进程环境,而不是这套 HTTP 授权流程。不要只为了协议形式对称,就把远程 OAuth 设计搬到 stdio 中。
远程 MCP 授权中的角色
MCP 授权规范定义了三种角色:
- MCP 客户端充当 OAuth 客户端。
- MCP 服务器充当受保护的资源服务器。
- 授权服务器验证资源所有者身份并签发 access token。
授权服务器可以属于同一服务,也可以是独立的身份平台。MCP 服务器仍负责验证 token 并强制执行访问控制。
从受保护资源开始发现流程
客户端在没有有效授权的情况下调用受保护 MCP 服务器时,服务器返回 401,并通过 WWW-Authenticate header 指向受保护资源元数据。该元数据告诉客户端,哪些授权服务器可以为当前资源签发 token。
客户端随后读取 OAuth 授权服务器元数据,找到授权端点和 token 端点。MCP 同时要求提供受保护资源元数据和授权服务器元数据,因为通用客户端可能连接到一台此前从未见过的服务器。
将请求绑定到 MCP 服务器
客户端在授权请求和 token 请求中都包含 resource 参数,用于标识目标 MCP 服务器。MCP 服务器随后必须确认收到的 token 确实为自身签发。
Audience 绑定可以防止为一个服务签发的 token 被重放到另一个服务。即使签名有效,只要 audience 错误,也不能接受该 token。
保护授权码
公开 MCP 客户端无法安全保存 client secret。规范要求使用 Proof Key for Code Exchange,即 PKCE,让启动流程的客户端在交换授权码时证明它持有 verifier。
Redirect URI 必须预先注册并精确匹配。客户端应使用并验证 state 值,将回调与最初发起的请求绑定。除 localhost 开发重定向外,必须使用 HTTPS。
只通过 Authorization header 发送 token
每个受保护 HTTP 请求都携带:
Authorization: Bearer <access-token>
MCP 规范禁止在查询字符串中传递 access token。与 header 相比,URL 更容易泄露到浏览器历史记录、反向代理日志、分析系统、截图和 referrer 数据中。
无效或已过期的 token 返回 401。身份有效但 scope 或权限不足时返回 403。
绝不将 MCP token 传递到下游
Access token 的目标是 MCP 服务器,服务器不得将其转发给第三方 API。如果工具需要调用上游服务,MCP 服务器应充当独立 OAuth 客户端,或获取专门用于该服务的后端凭据。
Token 透传会造成 confused deputy 问题,并破坏 audience 边界。MCP API 密钥指南介绍了这些上游凭据应存放在哪里。
对用户、租户、资源和操作逐层授权
Scope 只是其中一层。验证 token 后,还要根据当前应用状态计算访问权限:
- 当前代表哪个用户或服务身份?
- 当前启用哪个租户或组织?
- 请求的资源是否属于该租户?
- 该身份的角色是否允许执行此操作?
- 操作是否需要当前有效的审批或策略决策?
- 凭据是否仍然有效且未超出限制?
下游 API 应再次执行资源级授权。仅仅把工具命名为 read_invoice,并不能靠声明让 API 调用变成只读。
将高影响操作的审批分开处理
OAuth consent 授予的是一类访问权限,不应被视为以后每次删除、购买或大范围变更的审批。执行高影响操作时,应展示确切资源和影响。
MCP 工具规范建议在工具调用前清楚地向用户展示信息并取得确认。安全管理基础设施指南进一步为云资源操作增加了 plan 和 apply 边界。
测试失败场景
| 测试 | 预期结果 |
|---|---|
| 没有 bearer token | 返回 401,并包含受保护资源元数据的位置 |
| Token 已过期 | 返回 401,不执行后端操作 |
| Token 的 audience 是其他服务 | 在工具分发前拒绝 |
| Token 有效但缺少 scope | 返回 403 |
| Scope 正确,但资源属于其他租户 | 拒绝请求且不泄露资源信息 |
| 将 MCP token 传给上游 API | 从设计上杜绝这种情况 |
| Redirect URI 被修改 | 拒绝授权 |
| 重放破坏性请求 | 只产生一次影响,或要求审批 |
还要检查日志、错误追踪、链路追踪和分析系统中是否出现 access token 或 refresh token。服务器如果记录了凭据,校验逻辑再正确也无济于事。
追踪一枚 token 的终点
从第一个未授权请求开始,追踪签发的 access token,直至 MCP 服务器完成校验。之后再追踪独立的上游凭据。如果同一枚 token 跨越了两道边界,应先修复这一问题,再添加工具。
下方的提示词会在不调用服务器的情况下生成这份追踪记录和缺失的测试。