1. 什么是 MCP 授权? #
MCP 授权使 MCP 客户端能够代表用户向受保护的 MCP 服务器发起请求。当服务器需要验证「谁在访问」时,客户端通过 OAuth 2.1 流程获取访问令牌,并在请求中携带令牌。
协议修订版:2025-11-25
| 通俗理解 | 说明 |
|---|---|
| 可选 | 授权对 MCP 实现是可选的;仅在需要保护资源时使用 |
| 基于 HTTP | 本规范针对 HTTP 传输;STDIO 传输从环境获取凭据 |
| OAuth 2.1 | 基于 OAuth 2.1、RFC 9728、RFC 8707 等标准 |
典型场景:用户用 VS Code 连接公司的远程 MCP 服务器(如内部文档、数据库)。首次连接时,VS Code 会打开浏览器让用户登录公司账号,登录成功后拿到令牌,后续请求自动携带令牌访问受保护资源。
2. 本章你将学到 #
- 授权涉及的角色与协议要求
- 授权服务器发现流程
- 客户端注册方式(Client ID 元数据、预注册、动态注册)
- 授权流程步骤、错误处理与安全要点
若需动手实现带授权的 MCP 服务器,详见 理解 MCP 中的授权。
3. 协议要求 #
| 传输方式 | 授权建议 |
|---|---|
| HTTP | 应当符合本规范 |
| STDIO | 不应使用 HTTP 授权,应从环境变量等获取凭据 |
| 其他 | 必须遵循其协议既定的安全最佳实践 |
4. 角色 #
用户 ──► MCP 客户端(如 VS Code)──► MCP 服务器(受保护资源)
│
└──► 授权服务器(登录、签发令牌)| 角色 | 通俗理解 | 说明 |
|---|---|---|
| MCP 服务器 | 被保护的一方 | 充当 OAuth 资源服务器,验证令牌后响应请求 |
| MCP 客户端 | 代用户办事的一方 | 充当 OAuth 客户端,代表用户发起请求、携带令牌 |
| 授权服务器 | 发「通行证」的一方 | 与用户登录、签发访问令牌;可与 MCP 服务器同址或独立 |
5. 概述 #
| 要求 | 说明 |
|---|---|
| 授权服务器 | 必须实现 OAuth 2.1,并为机密/公共客户端采取安全措施 |
| Client ID 元数据 | 授权服务器和客户端应当支持 OAuth Client ID Metadata Documents |
| 动态注册 | 可以支持 RFC7591 Dynamic Client Registration |
| MCP 服务器 | 必须实现 RFC9728 Protected Resource Metadata |
| 发现机制 | 授权服务器必须提供 OAuth 2.0 元数据或 OIDC Discovery 至少一种;客户端必须支持两种 |
6. 授权服务器发现 #
客户端首次请求受保护服务器时,会收到 401,需要知道「去哪登录、去哪换令牌」。发现就是客户端如何找到授权服务器地址的过程。
6.1 发现流程 #
MCP 服务器通过以下方式向客户端告知授权服务器位置:
| 方式 | 说明 |
|---|---|
| WWW-Authenticate 头 | 401 响应中带 resource_metadata 参数,指向资源元数据 URL |
| Well-Known URI | 如 https://example.com/.well-known/oauth-protected-resource 或带路径的变体 |
客户端应当优先使用 WWW-Authenticate 中的 URL;否则回退到 well-known URI。
401 示例(带 scope 指导):
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
scope="files:read"6.2 授权服务器元数据发现 #
客户端根据 authorization_servers 中的 issuer URL,按优先级尝试 OAuth 2.0 元数据或 OIDC Discovery 端点,获取 authorization_endpoint、token_endpoint 等。
6.3 发现时序图 #
7. 客户端注册方式 #
在 OAuth 中,客户端需要先在授权服务器上「登记」自己,才能参与授权流程。MCP 支持多种登记方式:
| 方式 | 适用场景 | 优先级 |
|---|---|---|
| 预注册 | 客户端与服务器已有关系 | 1 |
| Client ID Metadata Documents | 无既有关系(最常见) | 2 |
| Dynamic Client Registration | 向后兼容或特定需求 | 3 |
| 用户手动输入 | 无其他选项 | 4 |
7.1 Client ID Metadata Documents #
通俗理解:客户端不用提前去授权服务器注册,而是把自己的「身份证」(元数据 JSON)放在一个 HTTPS 地址上。授权服务器在授权时去取这个文档,验证后即可完成登记。
客户端使用 HTTPS URL 作为 client_id,该 URL 指向包含客户端元数据的 JSON 文档。授权服务器获取并验证该文档。
元数据示例:
{
"client_id": "https://app.example.com/oauth/client-metadata.json",
"client_name": "Example MCP Client",
"redirect_uris": [
"http://127.0.0.1:3000/callback",
"http://localhost:3000/callback"
],
"grant_types": ["authorization_code"],
"response_types": ["code"],
"token_endpoint_auth_method": "none"
}授权服务器通过元数据中的 client_id_metadata_document_supported: true 表明支持此方式。
7.2 预注册 #
客户端使用预注册的 client_id(及 client credentials,若适用),可硬编码或由用户输入。
7.3 Dynamic Client Registration #
客户端向授权服务器的 registration_endpoint 发送 POST 请求,动态获取 client ID。用于向后兼容。
8. 范围选择策略 #
Scope(范围)表示「能访问什么」。客户端在授权时应请求最小必要的 scope,避免一次性要全部权限。
| 优先级 | 策略 |
|---|---|
| 1 | 若 401 的 WWW-Authenticate 提供 scope 参数,使用它 |
| 2 | 否则使用 Protected Resource Metadata 的 scopes_supported 全部 scope;若未定义则省略 |
遵循最小权限原则;额外 scope 通过 Scope Challenge 处理 逐步请求。
9. 授权流程 #
完整流程可概括为 8 步:
- 客户端发起未认证请求 → 收到 401
- 获取资源元数据 → 提取授权服务器
- 获取授权服务器元数据
- 选择客户端注册方式(Client ID 元数据 / 预注册 / 动态注册)
- 生成 PKCE 参数,包含
resource参数 - 打开浏览器 → 用户授权 → 重定向回带授权码
- 用授权码 + code_verifier 交换访问令牌
- 后续请求携带
Authorization: Bearer <token>
resource 参数:客户端必须在授权请求和 token 请求中包含 resource,标识目标 MCP 服务器(如 https://mcp.example.com)。详见 RFC 8707。
10. 错误处理 #
| 状态码 | 含义 |
|---|---|
| 401 | 需要授权或令牌无效 |
| 403 | scope 不足或权限不足 |
| 400 | 授权请求格式错误 |
10.1 Scope Challenge 处理 #
当客户端持有令牌但 scope 不足时,服务器应当返回:
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
scope="files:read files:write",
resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource"客户端应当通过 step-up 授权流程请求更大 scope 的令牌,或重试有限次数后中止。
11. 安全要点 #
| 要点 | 说明 |
|---|---|
| 令牌受众 | 客户端必须发送 resource 参数;服务器必须验证令牌是专门为其签发 |
| 令牌透传 | 服务器不得接受或转发非为其签发的令牌 |
详见 安全最佳实践 中的令牌透传、混淆代理等。
| 要点 | 说明 |
|---|---|
| PKCE | 客户端必须实现 PKCE,使用 S256;授权前必须验证服务器支持 |
| HTTPS | 授权端点、redirect URI 必须使用 HTTPS(localhost 除外) |
| 开放重定向 | 授权服务器必须精确校验 redirect URI |
| Client ID 元数据 | 授权服务器获取元数据时需防范 SSRF;localhost redirect 需额外警告 |
12. 术语速查 #
| 术语 | 通俗理解 |
|---|---|
| access_token | 访问令牌,客户端请求时放在 Authorization: Bearer <token> 中 |
| scope | 权限范围,如 files:read 表示可读文件 |
| resource | 目标资源标识,如 MCP 服务器的 URL,用于确保令牌只发给该服务器 |
| PKCE | 防止授权码被截获的扩展,客户端生成 code_verifier 和 code_challenge |