协议修订: 2025-11-25
简介
目的与范围
模型上下文协议在传输层提供授权功能,使 MCP 客户端能够代表资源所有者向受限的 MCP 服务器发起请求。本规范定义了基于 HTTP 传输的授权流程。协议要求
授权对于 MCP 实现是可选的 (OPTIONAL)。当支持授权时:- 使用基于 HTTP 传输的实现应当 (SHOULD) 符合本规范。
- 使用 STDIO 传输的实现不应 (SHOULD NOT) 遵循本规范,而应从环境中检索凭据。
- 使用替代传输方式的实现必须 (MUST) 遵循其协议既定的安全最佳实践。
标准合规性
此授权机制基于下述既定规范,但仅实现其功能的一个选定子集,以在保持简洁性的同时确保安全性和互操作性:- OAuth 2.1 IETF 草案 (draft-ietf-oauth-v2-1-13)
- OAuth 2.0 授权服务器元数据 (RFC8414)
- OAuth 2.0 动态客户端注册协议 (RFC7591)
- OAuth 2.0 受保护资源元数据 (RFC9728)
- OAuth 客户端 ID 元数据文档 (draft-ietf-oauth-client-id-metadata-document-00)
角色
受保护的 MCP 服务器 充当 OAuth 2.1 资源服务器,能够接受并响应带有访问令牌的受保护资源请求。 MCP 客户端 充当 OAuth 2.1 客户端,代表资源所有者发起受保护资源请求。 授权服务器 负责与用户交互(如果需要)并颁发用于 MCP 服务器的访问令牌。授权服务器的具体实现细节超出了本规范的范围。它可以与资源服务器托管在一起,也可以是独立的实体。授权服务器发现章节规定了 MCP 服务器如何向客户端指明其对应授权服务器的位置。概述
- 授权服务器必须 (MUST) 实现 OAuth 2.1,并针对机密客户端和公共客户端采取适当的安全措施。
- 授权服务器和 MCP 客户端应当 (SHOULD) 支持 OAuth 客户端 ID 元数据文档 (draft-ietf-oauth-client-id-metadata-document-00)。
- 授权服务器和 MCP 客户端可以 (MAY) 支持 OAuth 2.0 动态客户端注册协议 (RFC7591)。
- MCP 服务器必须 (MUST) 实现 OAuth 2.0 受保护资源元数据 (RFC9728)。MCP 客户端必须 (MUST) 使用 OAuth 2.0 受保护资源元数据进行授权服务器发现。
-
MCP 授权服务器必须 (MUST) 至少提供以下一种发现机制:
- OAuth 2.0 授权服务器元数据 (RFC8414)
- OpenID Connect Discovery 1.0
授权服务器发现
本章节描述了 MCP 服务器向 MCP 客户端通告其关联授权服务器的机制,以及 MCP 客户端确定授权服务器端点和支持功能的发现过程。授权服务器位置
MCP 服务器必须 (MUST) 实现 OAuth 2.0 受保护资源元数据 (RFC9728) 规范以指明授权服务器的位置。MCP 服务器返回的受保护资源元数据文档必须 (MUST) 包含authorization_servers 字段,且至少包含一个授权服务器。 authorization_servers 的具体用法超出了本规范的范围;实现者应参考 OAuth 2.0 受保护资源元数据 (RFC9728) 以获取实现细节指导。 实现者应注意,受保护资源元数据文档可以定义多个授权服务器。选择使用哪个授权服务器的责任在于 MCP 客户端,应遵循 RFC9728 第 7.6 节 “授权服务器” 中指定的指南。受保护资源元数据发现要求
MCP 服务器必须 (MUST) 实现以下发现机制之一,以向 MCP 客户端提供授权服务器位置信息:-
WWW-Authenticate 响应头:在返回
401 Unauthorized响应时,在WWW-AuthenticateHTTP 响应头的resource_metadata下包含资源元数据 URL,如 RFC9728 第 5.1 节所述。 -
周知 (Well-Known) URI:在 RFC9728 指定的周知 URI 提供元数据。这可以是:
- 在服务器 MCP 端点的路径:
https://example.com/public/mcp可以在https://example.com/.well-known/oauth-protected-resource/public/mcp托管元数据 - 在根目录:
https://example.com/.well-known/oauth-protected-resource
- 在服务器 MCP 端点的路径:
WWW-Authenticate 响应头中的资源元数据 URL;否则,它们必须 (MUST) 按照上述顺序列出的周知 URI 进行构造和请求。 MCP 服务器应当 (SHOULD) 在 WWW-Authenticate 响应头中包含一个 scope 参数(如 RFC 6750 第 3 节所定义),以指示访问该资源所需的范围。这遵循最小权限原则,并防止客户端请求过度权限,为客户端在授权期间请求适当的范围提供即时指导。 WWW-Authenticate 挑战中包含的范围可以 (MAY) 与 scopes_supported 匹配,或者是其子集或超集,或者是既非严格子集也非超集的另一种组合。客户端不得 (MUST NOT) 假设挑战范围集与 scopes_supported 之间存在任何特定的集合关系。客户端必须 (MUST) 将挑战中提供的范围视为满足当前请求的权威范围。服务器应当 (SHOULD) 努力保持构造范围集的一致性,但并不要求通过 scopes_supported 公开每一个动态颁发的范围。 带有范围指导的 401 响应示例:WWW-Authenticate 响应头,并对 MCP 服务器的 HTTP 401 Unauthorized 响应做出适当反应。 如果 scope 参数缺失,客户端应当 (SHOULD) 应用 范围选择策略 章节中定义的备选行为。授权服务器元数据发现
为了处理不同的颁发者 URL 格式,并确保与 OAuth 2.0 授权服务器元数据和 OpenID Connect Discovery 1.0 规范的互操作性,MCP 客户端在发现授权服务器元数据时必须 (MUST) 尝试多个周知端点。 发现方法基于 RFC8414 第 3.1 节 “授权服务器元数据请求”(用于 OAuth 2.0 授权服务器元数据发现)和 RFC8414 第 5 节 “兼容性说明”(用于 OpenID Connect Discovery 1.0 互操作性)。 对于带有路径组件的颁发者 URL(例如https://auth.example.com/tenant1),客户端必须 (MUST) 按以下优先级顺序尝试端点:- 路径插入式的 OAuth 2.0 授权服务器元数据:
https://auth.example.com/.well-known/oauth-authorization-server/tenant1 - 路径插入式的 OpenID Connect Discovery 1.0:
https://auth.example.com/.well-known/openid-configuration/tenant1 - 路径追加式的 OpenID Connect Discovery 1.0:
https://auth.example.com/tenant1/.well-known/openid-configuration
https://auth.example.com),客户端必须 (MUST) 尝试:
- OAuth 2.0 授权服务器元数据:
https://auth.example.com/.well-known/oauth-authorization-server - OpenID Connect Discovery 1.0:
https://auth.example.com/.well-known/openid-configuration
授权服务器发现时序图
下图概述了一个示例流程:客户端注册方式
MCP 支持三种客户端注册机制。请根据您的场景选择:- 客户端 ID 元数据文档:当客户端和服务器没有事先关系时(最常见)
- 预注册:当客户端和服务器已有现有关系时
- 动态客户端注册:用于向后兼容或特定需求
- 如果客户端有可用的预注册客户端信息,则使用该信息
- 如果授权服务器指示支持(通过 OAuth 授权服务器元数据中的
client_id_metadata_document_supported),则使用客户端 ID 元数据文档 - 如果授权服务器支持(通过 OAuth 授权服务器元数据中的
registration_endpoint),则使用动态客户端注册作为备选 - 如果没有其他选项可用,提示用户输入客户端信息
客户端 ID 元数据文档
MCP 客户端和授权服务器应当 (SHOULD) 支持如 OAuth 客户端 ID 元数据文档 中指定的机制。这种方法允许客户端使用 HTTPS URL 作为客户端标识符,该 URL 指向包含客户端元数据的 JSON 文档。这解决了 MCP 中常见的服务器和客户端之间没有预先存在关系的场景。实现要求
支持客户端 ID 元数据文档的 MCP 实现必须 (MUST) 遵循 OAuth 客户端 ID 元数据文档 中规定的要求。关键要求包括: 对于 MCP 客户端:- 客户端必须 (MUST) 按照 RFC 要求在 HTTPS URL 上托管其元数据文档
client_idURL 必须 (MUST) 使用 “https” 协议并包含路径组件,例如https://example.com/client.json- 元数据文档必须 (MUST) 至少包含以下属性:
client_id、client_name、redirect_uris - 客户端必须 (MUST) 确保元数据中的
client_id值与文档 URL 完全匹配 - 客户端可以 (MAY) 使用
private_key_jwt进行客户端身份验证(例如,针对令牌端点的请求),并按照 客户端 ID 元数据文档第 6.2 节 所述配置适当的 JWKS
- 应当 (SHOULD) 在遇到 URL 格式的 client_id 时获取元数据文档
- 必须 (MUST) 验证获取到的文档的
client_id与 URL 完全匹配 - 应当 (SHOULD) 遵循 HTTP 缓存头缓存元数据
- 必须 (MUST) 将授权请求中提供的重定向 URI 与元数据文档中的进行对比验证
- 必须 (MUST) 验证文档结构为有效的 JSON 并包含必需字段
- 应当 (SHOULD) 遵循 客户端 ID 元数据文档第 6 节 中的安全考虑
元数据文档示例
客户端 ID 元数据文档流程
下图展示了使用客户端 ID 元数据文档时的完整流程:发现
授权服务器通过在 OAuth 授权服务器元数据中包含以下属性,来通告其支持使用客户端 ID 元数据文档的客户端:预注册
MCP 客户端应当 (SHOULD) 支持静态客户端凭据选项,例如由预注册流程提供的凭据。这可以是:- 专门为 MCP 客户端硬编码一个客户端 ID(以及适用的客户端凭据),用于与该授权服务器交互,或者
- 向用户提供一个界面,允许他们在自己注册 OAuth 客户端后(例如通过服务器托管的配置界面)输入这些详细信息。
动态客户端注册
MCP 客户端和授权服务器可以 (MAY) 支持 OAuth 2.0 动态客户端注册协议 RFC7591,以允许 MCP 客户端在无需用户交互的情况下获取 OAuth 客户端 ID。此选项是为与早期版本的 MCP 授权规范保持向后兼容而保留的。范围 (Scope) 选择策略
在实现授权流程时,MCP 客户端应当 (SHOULD) 遵循最小权限原则,仅请求其预期操作所必需的范围 (scopes)。在初始授权握手期间,MCP 客户端应当 (SHOULD) 遵循以下范围选择优先级:- 使用
scope参数:如果 401 响应中初始的WWW-Authenticate响应头提供了该参数,则使用它 - 如果
scope不可用:使用受保护资源元数据文档中scopes_supported定义的所有范围;如果scopes_supported未定义,则省略scope参数。
scopes_supported 字段旨在表示基本功能所需的最小范围集(参见 范围最小化),额外的范围通过 范围挑战处理 章节中描述的升级授权流程步骤进行增量请求。授权流程步骤
完整的授权流程如下:资源参数实现
MCP 客户端必须 (MUST) 实现 RFC 8707 中定义的 OAuth 2.0 资源指示器 (Resource Indicators),以明确指定请求令牌的目标资源。resource 参数:
- 必须 (MUST) 同时包含在授权请求和令牌请求中。
- 必须 (MUST) 标识客户端打算使用该令牌的 MCP 服务器。
- 必须 (MUST) 使用 RFC 8707 第 2 节 定义的 MCP 服务器规范 URI。
规范服务器 URI
就本规范而言,MCP 服务器的规范 URI 被定义为 RFC 8707 第 2 节 中指定的资源标识符,并与 RFC 9728 中的resource 参数对齐。 MCP 客户端应当 (SHOULD) 为其打算访问的 MCP 服务器提供尽可能具体的 URI,遵循 RFC 8707 中的指导。虽然规范形式使用小写的协议和主机组件,但为了健壮性和互操作性,实现应当 (SHOULD) 接受大写的协议和主机组件。 有效的规范 URI 示例:https://mcp.example.com/mcphttps://mcp.example.comhttps://mcp.example.com:8443https://mcp.example.com/server/mcp(当需要路径组件来识别单个 MCP 服务器时)
mcp.example.com(缺少协议)https://mcp.example.com#fragment(包含片段)
注意: 虽然根据 RFC 3986,例如,如果访问https://mcp.example.com/(带尾部斜杠)和https://mcp.example.com(不带尾部斜杠)在技术上都是有效的绝对 URI,但为了更好的互操作性,实现应当 (SHOULD) 一致地使用不带尾部斜杠的形式,除非尾部斜杠对特定资源具有语义意义。
https://mcp.example.com 处的 MCP 服务器,授权请求将包含:
访问令牌使用
令牌要求
向 MCP 服务器发起请求时的访问令牌处理必须 (MUST) 符合 OAuth 2.1 第 5 节 “资源请求” 中定义的要求。具体而言:- MCP 客户端必须 (MUST) 使用 OAuth 2.1 第 5.1.1 节 定义的 Authorization 请求头字段
- 访问令牌不得 (MUST NOT) 包含在 URI 查询字符串中
令牌处理
MCP 服务器作为 OAuth 2.1 资源服务器,必须 (MUST) 按照 OAuth 2.1 第 5.2 节 的描述验证访问令牌。根据 RFC 8707 第 2 节,MCP 服务器必须 (MUST) 验证访问令牌是专门为其作为预期受众颁发的。如果验证失败,服务器必须 (MUST) 根据 OAuth 2.1 第 5.3 节 的错误处理要求做出响应。无效或过期的令牌必须 (MUST) 收到 HTTP 401 响应。 MCP 客户端不得 (MUST NOT) 向 MCP 服务器发送除该服务器对应的授权服务器颁发以外的令牌。 MCP 服务器必须 (MUST) 仅接受对其自身资源有效的令牌。 MCP 服务器不得 (MUST NOT) 接受或传输任何其他令牌。错误处理
服务器必须 (MUST) 为授权错误返回适当的 HTTP 状态码:| 状态码 | 描述 | 用途 |
|---|---|---|
| 401 | Unauthorized (未授权) | 需要授权或令牌无效 |
| 403 | Forbidden (禁止访问) | 无效的范围或权限不足 |
| 400 | Bad Request (错误请求) | 格式错误的授权请求 |
范围挑战 (Scope Challenge) 处理
本章节涵盖了在客户端已拥有令牌但需要额外权限的运行时操作期间,如何处理范围不足错误。这遵循 OAuth 2.1 第 5 节 定义的错误处理模式,并利用了 RFC 9728 (OAuth 2.0 受保护资源元数据) 中的元数据字段。运行时范围不足错误
当客户端在运行时操作中使用范围不足的访问令牌发起请求时,服务器应当 (SHOULD) 返回:HTTP 403 Forbidden状态码(根据 RFC 6750 第 3.1 节)- 带有
Bearer方案和额外参数的WWW-Authenticate响应头:error="insufficient_scope"- 指明具体的授权失败类型scope="required_scope1 required_scope2"- 指定该操作所需的最小范围resource_metadata- 受保护资源元数据文档的 URI(与 401 响应保持一致)error_description(可选) - 错误的易读描述
scope 参数中包含满足当前请求所需的范围。 服务器可以灵活确定要包含哪些范围:- 最小化方法:仅包含该特定操作新要求的范围。如果也需要任何现有的已授予范围,请一并包含,以防止客户端丢失之前已授予的权限。
- 推荐方法:同时包含相关的现有范围和新要求的范围,以防止客户端丢失之前已授予的权限
- 扩展方法:包含现有范围、新要求的范围,以及通常协同工作的相关范围
升级授权流程
客户端将在初始授权或运行时收到与范围相关的错误 (insufficient_scope)。客户端应当 (SHOULD) 通过升级授权流程请求具有更大范围集的新访问令牌,或以其他适当方式处理错误。代表用户操作的客户端应当 (SHOULD) 尝试升级授权流程。代表自身操作的客户端 (client_credentials 客户端) 可以 (MAY) 尝试升级授权流程或立即中止请求。 流程如下:- 从授权服务器响应或
WWW-Authenticate响应头中解析错误信息 - 按照 范围选择策略 中的概述确定所需范围。
- 使用确定的范围集发起(重新)授权
- 使用新的授权重试原始请求(重试次数不超过几次),并将其视为永久性授权失败
安全注意事项
实现必须 (MUST) 遵循 OAuth 2.1 第 7 节 “安全考虑” 中阐述的 OAuth 2.1 安全最佳实践。令牌受众绑定与验证
当授权服务器支持该功能时,RFC 8707 资源指示器通过将令牌绑定到其预期受众来提供关键的安全优势。为了促进当前和未来的采用:- MCP 客户端必须 (MUST) 按照 资源参数实现 章节的规定,在授权请求和令牌请求中包含
resource参数 - MCP 服务器必须 (MUST) 验证向其出示的令牌是专门为其使用而颁发的
令牌窃取
攻击者如果获取了客户端存储的令牌,或者在服务器上缓存或记录的令牌,就可以通过看起来合法的请求访问受保护资源。 客户端和服务器必须 (MUST) 实现安全的令牌存储并遵循 OAuth 最佳实践,如 OAuth 2.1 第 7.1 节 所述。 授权服务器应当 (SHOULD) 颁发短效访问令牌,以减少令牌泄露的影响。对于公共客户端,授权服务器必须 (MUST) 按照 OAuth 2.1 第 4.3.1 节 “令牌端点扩展” 的描述轮换刷新令牌。通信安全
实现必须 (MUST) 遵循 OAuth 2.1 第 1.5 节 “通信安全”。 具体而言:- 所有授权服务器端点必须 (MUST) 通过 HTTPS 提供服务。
- 所有重定向 URI 必须 (MUST) 为
localhost或使用 HTTPS。
授权码保护
获得授权响应中包含的授权码的攻击者可以尝试将该授权码兑换为访问令牌,或以其他方式使用该授权码。(在 OAuth 2.1 第 7.5 节 中有进一步描述) 为了缓解这种情况,MCP 客户端必须 (MUST) 根据 OAuth 2.1 第 7.5.2 节 实现 PKCE,并必须 (MUST) 在继续授权前验证 PKCE 支持。PKCE 通过要求客户端创建秘密的验证器-挑战对 (verifier-challenge pair),确保只有原始请求者可以用授权码交换令牌,从而帮助防止授权码拦截和注入攻击。 在技术能力允许的情况下,MCP 客户端必须 (MUST) 使用S256 代码挑战方法,这是 OAuth 2.1 第 4.1.1 节 要求的。 由于 OAuth 2.1 和 PKCE 规范未定义客户端发现 PKCE 支持的机制,MCP 客户端必须 (MUST) 依靠授权服务器元数据来验证此功能:-
OAuth 2.0 授权服务器元数据:如果缺失
code_challenge_methods_supported,则说明授权服务器不支持 PKCE,MCP 客户端必须 (MUST) 拒绝继续流程。 -
OpenID Connect Discovery 1.0:虽然 OpenID 提供者元数据 未定义
code_challenge_methods_supported,但该字段通常由 OpenID 提供者包含。MCP 客户端必须 (MUST) 验证提供者元数据响应中是否存在code_challenge_methods_supported。如果该字段缺失,MCP 客户端必须 (MUST) 拒绝继续流程。
code_challenge_methods_supported,以确保 MCP 兼容性。
开放重定向
攻击者可能会精心构造恶意的重定向 URI,将用户引导至钓鱼网站。 MCP 客户端必须 (MUST) 在授权服务器上注册重定向 URI。 授权服务器必须 (MUST) 根据预注册的值验证精确的重定向 URI,以防止重定向攻击。 MCP 客户端应当 (SHOULD) 在授权码流程中使用并验证 state 参数,并丢弃任何不包含 state 或 state 与原始值不匹配的结果。 授权服务器必须 (MUST) 采取预防措施,防止将用户代理重定向到不可信的 URI,遵循 OAuth 2.1 第 7.12.2 节 中的建议。 授权服务器应当 (SHOULD) 仅在信任重定向 URI 的情况下才自动重定向用户代理。如果 URI 不被信任,授权服务器可以告知用户并依靠用户做出正确决定。客户端 ID 元数据文档安全
在实现客户端 ID 元数据文档时,授权服务器必须 (MUST) 考虑 OAuth 客户端 ID 元数据文档第 6 节 中详述的安全影响。关键考虑因素包括:授权服务器滥用保护
授权服务器从未知客户端获取一个 URL 作为输入,并抓取该 URL。恶意客户端可以利用这一点触发授权服务器向任意 URL 发起请求,例如向授权服务器有权访问的私有管理端点发起请求。 获取元数据文档的授权服务器应当 (SHOULD) 考虑 服务端请求伪造 (SSRF) 风险,如 OAuth 客户端 ID 元数据文档:服务端请求伪造 (SSRF) 攻击 中所述。Localhost 重定向 URI 风险
客户端 ID 元数据文档本身无法防止localhost URL 冒充。攻击者可以通过以下方式声称自己是任何客户端:
- 提供合法客户端的元数据 URL 作为其
client_id - 绑定到任意
localhost端口,并将该地址作为 redirect_uri 提供 - 当用户批准时,通过重定向接收授权码
- 应当 (SHOULD) 对仅限
localhost的重定向 URI 显示额外警告 - 可以 (MAY) 为了增强安全性而要求额外的证明 (attestation) 机制
- 必须 (MUST) 在授权期间清晰显示重定向 URI 的主机名
信任策略
授权服务器可以 (MAY) 实现基于域名的信任策略:- 受信任域名的白名单(针对受保护服务器)
- 接受任何 HTTPS
client_id(针对开放服务器) - 对未知域名进行声誉检查
- 基于域名年龄或证书验证的限制
- 突出显示 CIMD 和其他关联的客户端主机名以防止钓鱼
混淆代理问题
攻击者可以利用充当第三方 API 中间方的 MCP 服务器,导致 混淆代理漏洞。通过使用窃取的授权码,他们可以在未经用户同意的情况下获取访问令牌。 使用静态客户端 ID 的 MCP 代理服务器在转发到第三方授权服务器(可能需要额外同意)之前,必须 (MUST) 为每个动态注册的客户端获得用户同意。访问令牌权限限制
如果 MCP 服务器接受为其他资源颁发的令牌,攻击者可以获得未经授权的访问或以其他方式破坏服务器。 此漏洞有两个关键维度:- 受众验证失败。 当 MCP 服务器不验证令牌是否专门用于它时(例如,通过 RFC9068 中提到的受众声明),它可能会接受最初为其他服务颁发的令牌。这破坏了基本的 OAuth 安全边界,允许攻击者在非预期的不同服务之间重用合法令牌。
- 令牌透传。 如果 MCP 服务器不仅接受受众错误的令牌,还将这些未经修改的令牌转发给下游服务,则可能会导致 “混淆代理”问题,下游 API 可能会错误地信任该令牌,就像它直接来自 MCP 服务器一样,或者假设该令牌已被上游 API 验证。有关其他详细信息,请参阅安全最佳实践指南的 令牌透传章节。
resource 参数,以明确指定请求令牌的目标资源。这一要求与 RFC 9728 第 7.4 节 中的建议一致。这确保了访问令牌与其预期资源绑定,且不能在不同服务之间被误用。MCP 授权扩展
核心协议有多个授权扩展,定义了额外的授权机制。这些扩展是:- 可选的 - 实现可以选择采用这些扩展
- 增量式的 - 扩展不会修改或破坏核心协议功能;它们在保留核心协议行为的同时增加了新功能
- 可组合的 - 扩展是模块化的,旨在协同工作而不产生冲突,允许实现同时采用多个扩展
- 独立版本控制 - 扩展遵循核心 MCP 版本周期,但也可以根据需要采用独立版本号