授权
1. 引言
1.1 目的和范围
模型上下文协议(MCP)在传输层提供授权功能,使 MCP 客户端能够代表资源所有者向受限的 MCP 服务器发出请求。本规范定义了基于 HTTP 的传输的授权流程。
1.2 协议要求
MCP 实现中的授权是 可选的。当支持授权时:
- 使用基于 HTTP 的传输的实现 应该 遵循本规范。
- 使用 STDIO 传输的实现 不应 遵循本规范,而应从环境中检索凭据。
- 使用其他传输的实现 必须 遵循其协议的已建立安全最佳实践。
1.3 标准合规性
此授权机制基于以下列出的已有规范,但仅实现其功能的一个选定子集,以确保安全性和互操作性,同时保持简单性:
- OAuth 2.1 IETF 草案
- OAuth 2.0 授权服务器元数据 (RFC8414)
- OAuth 2.0 动态客户端注册协议 (RFC7591)
2. 授权流程
2.1 概述
- MCP 授权实现 必须 实现 OAuth 2.1,并为机密客户端和公共客户端采取适当的安全措施。
- MCP 授权实现 应该 支持 OAuth 2.0 动态客户端注册协议 (RFC7591)。
- MCP 服务器 应该 并且 MCP 客户端 必须 实现 OAuth 2.0 授权服务器元数据 (RFC8414)。不支持授权服务器元数据的服务器 必须 遵循默认 URI 模式。
2.1.1 OAuth 授权类型
OAuth 指定了不同的流程或授权类型,这些是获取访问令牌的不同方式。每种方式针对不同的用例和场景。
MCP 服务器 应该 支持与其目标受众最契合的 OAuth 授权类型。例如:
- 授权码:当客户端代表(人类)最终用户操作时非常有用。
- 例如,一个代理调用由 SaaS 系统实现的 MCP 工具。
- 客户端凭据:客户端是另一个应用程序(非人类)。
- 例如,一个代理调用安全的 MCP 工具以检查特定商店的库存。无需模拟最终用户。
2.2 示例:授权码授权
这展示了用于用户授权的 OAuth 2.1 授权码授权类型的流程。
注意:以下示例假设 MCP 服务器同时充当授权服务器。然而,授权服务器可以作为独立的单独服务部署。
人类用户通过 Web 浏览器完成 OAuth 流程,获得一个标识其个人身份的访问令牌,允许客户端代表其操作。
当需要授权且客户端尚未证明其授权时,服务器 必须 以 HTTP 401 未授权 响应。
客户端在收到 HTTP 401 未授权 后启动 OAuth 2.1 IETF 草案 授权流程。
以下展示了使用 PKCE 的公共客户端的基本 OAuth 2.1 流程。
2.3 服务器元数据发现
为了进行服务器能力发现:
- MCP 客户端 必须 遵循 RFC8414 中定义的 OAuth 2.0 授权服务器元数据协议。
- MCP 服务器 应该 遵循 OAuth 2.0 授权服务器元数据协议。
- 不支持 OAuth 2.0 授权服务器元数据协议的 MCP 服务器 必须 支持备用 URL。
发现流程如下图所示:
2.3.1 服务器元数据发现头
MCP 客户端在服务器元数据发现期间 应该 包含头 MCP-Protocol-Version: <protocol-version>
,以允许 MCP 服务器根据 MCP 协议版本进行响应。
例如:MCP-Protocol-Version: 2024-11-05
2.3.2 授权基础 URL
授权基础 URL 必须 通过丢弃 MCP 服务器 URL 中的任何现有 path
组件来确定。例如:
如果 MCP 服务器 URL 是 https://api.example.com/v1/mcp
,那么:
- 授权基础 URL 为
https://api.example.com
- 元数据端点 必须 位于
https://api.example.com/.well-known/oauth-authorization-server
这确保授权端点始终位于托管 MCP 服务器的域名根级别,无论 MCP 服务器 URL 中是否有路径组件。
2.3.3 不支持元数据发现的服务器的备用方案
对于不实现 OAuth 2.0 授权服务器元数据的服务器,客户端 必须 使用相对于授权基础 URL(定义于 第 2.3.2 节)的以下默认端点路径:
端点 | 默认路径 | 描述 |
---|---|---|
授权端点 | /authorize | 用于授权请求 |
令牌端点 | /token | 用于令牌交换和刷新 |
注册端点 | /register | 用于动态客户端注册 |
例如,对于托管在 https://api.example.com/v1/mcp
的 MCP 服务器,默认端点将是:
https://api.example.com/authorize
https://api.example.com/token
https://api.example.com/register
客户端 必须 首先尝试通过元数据文档发现端点,然后再回退到默认路径。使用默认路径时,所有其他协议要求保持不变。
2.4 动态客户端注册
MCP 客户端和服务器 应该 支持 OAuth 2.0 动态客户端注册协议,以允许 MCP 客户端无需用户交互即可获得 OAuth 客户端 ID。这为客户端自动注册新服务器提供了标准化方式,这对 MCP 至关重要,因为:
- 客户端无法提前知道所有可能的服务器
- 手动注册会给用户带来不便
- 它支持与新服务器的无缝连接
- 服务器可以实现自己的注册策略
不支持动态客户端注册的任何 MCP 服务器需要提供获取客户端 ID(以及适用时的客户端密钥)的替代方式。对于此类服务器,MCP 客户端将需要:
- 为该 MCP 服务器硬编码客户端 ID(以及适用时的客户端密钥),或
- 向用户展示一个界面,允许他们在通过服务器托管的配置界面注册 OAuth 客户端后输入这些详细信息。
2.5 授权流程步骤
完整的授权流程如下:
2.5.1 决策流程概述
2.6 访问令牌使用
2.6.1 令牌要求
访问令牌处理 必须 符合 OAuth 2.1 第 5 节 中对资源请求的要求。具体来说:
- MCP 客户端 必须 使用授权请求头字段 第 5.1.1 节:
请注意,即使是同一逻辑会话中的请求,授权 必须 包含在从客户端到服务器的每个 HTTP 请求中。
- 访问令牌 不得 包含在 URI 查询字符串中。
示例请求:
2.6.2 令牌处理
资源服务器 必须 按照 第 5.2 节 的描述验证访问令牌。如果验证失败,服务器 必须 按照 第 5.3 节 的错误处理要求进行响应。无效或过期的令牌 必须 收到 HTTP 401 响应。
2.7 安全考虑
以下安全要求 必须 实现:
- 客户端 必须 遵循 OAuth 2.0 最佳实践安全存储令牌。
- 服务器 应该 强制执行令牌过期和轮换。
- 所有授权端点 必须 通过 HTTPS 提供。
- 服务器 必须 验证重定向 URI 以防止开放重定向漏洞。
- 重定向 URI 必须 是 localhost URL 或 HTTPS URL。
2.8 错误处理
服务器 必须 为授权错误返回适当的 HTTP 状态码:
状态码 | 描述 | 使用场景 |
---|---|---|
401 | 未授权 | 需要授权或令牌无效 |
403 | 禁止 | 无效的作用域或权限不足 |
400 | 请求错误 | 格式错误的授权请求 |
2.9 实现要求
- 实现 必须 遵循 OAuth 2.1 安全最佳实践。
- 所有客户端 必须 使用 PKCE。
- 为增强安全性 应该 实现令牌轮换。
- 根据安全要求 应该 限制令牌生命周期。
2.10 第三方授权流程
2.10.1 概述
MCP 服务器 可以 通过第三方授权服务器支持委托授权。在此流程中,MCP 服务器既充当 OAuth 客户端(对第三方授权服务器),又充当 OAuth 授权服务器(对 MCP 客户端)。
2.10.2 流程描述
第三方授权流程包括以下步骤:
- MCP 客户端使用 MCP 服务器启动标准 OAuth 流程。
- MCP 服务器将用户重定向到第三方授权服务器。
- 用户在第三方服务器上进行授权。
- 第三方服务器使用授权码重定向回 MCP 服务器。
- MCP 服务器用授权码交换第三方访问令牌。
- MCP 服务器生成绑定到第三方会话的自身访问令牌。
- MCP 服务器完成与 MCP 客户端的原始 OAuth 流程。
2.10.3 会话绑定要求
实现第三方授权的 MCP 服务器 必须:
- 维护第三方令牌与发行的 MCP 令牌之间的安全映射。
- 在接受 MCP 令牌之前验证第三方令牌状态。
- 实现适当的令牌生命周期管理。
- 处理第三方令牌的过期和续订。
2.10.4 安全考虑
在实现第三方授权时,服务器 必须:
- 验证所有重定向 URI。
- 安全存储第三方凭据。
- 实现适当的会话超时处理。
- 考虑令牌链的安全影响。
- 为第三方授权失败实现适当的错误处理。
3. 最佳实践
3.1 本地客户端作为公共 OAuth 2.1 客户端
我们强烈建议本地客户端作为公共客户端实现 OAuth 2.1:
- 使用代码挑战(PKCE)进行授权请求,以防止拦截攻击。
- 实现适合本地系统的安全令牌存储。
- 遵循令牌刷新最佳实践以维持会话。
- 正确处理令牌过期和续订。
3.2 授权元数据发现
我们强烈建议所有客户端实现元数据发现。这减少了用户手动提供端点的需求或客户端回退到定义的默认值。
3.3 动态客户端注册
由于客户端无法提前知道 MCP 服务器的集合,我们强烈建议实现动态客户端注册。这允许应用程序自动向 MCP 服务器注册,消除了用户手动获取客户端 ID 的需求。