授权

社区译文;来源: MCP 80041ab0

简介

目的与范围

模型上下文协议在传输层提供授权能力,使 MCP 客户端能够代表资源所有者向受限 MCP 服务器发出请求。本规范定义基于 HTTP 的传输所使用的授权流程。

协议要求

授权对 MCP 实现是 OPTIONAL 的。支持授权时:

  • 使用基于 HTTP 的传输的实现 SHOULD 遵循本规范。
  • 使用 STDIO 传输的实现 SHOULD NOT 遵循本规范,而应从环境中获取凭据。
  • 使用其他传输的实现 MUST 遵循其协议已确立的安全最佳实践。

标准合规性

本授权机制基于下列已有规范,但只实现其中选定的功能子集,以便在保持简洁的同时确保安全性与互操作性:

角色

受保护的 _MCP 服务器_充当 OAuth 2.1 资源服务器 ,能够使用访问令牌接收并响应受保护资源请求。

_MCP 客户端_充当 OAuth 2.1 客户端 ,代表资源所有者发出受保护资源请求。

_授权服务器_负责与用户交互(如有必要),并签发供 MCP 服务器使用的访问令牌。授权服务器的实现细节超出本规范范围。授权服务器可以与资源服务器共同托管,也可以是独立实体。授权服务器发现 规定 MCP 服务器如何向客户端指明其对应授权服务器的位置。

概述

  1. 授权服务器 MUST 实现 OAuth 2.1,并为机密客户端和公共客户端采取适当的安全措施。

  2. 授权服务器和 MCP 客户端 SHOULD 支持 OAuth Client ID Metadata Documents (draft-ietf-oauth-client-id-metadata-document-00 )。

  3. 授权服务器和 MCP 客户端 MAY 支持 OAuth 2.0 Dynamic Client Registration Protocol(RFC7591 )。请注意,动态客户端注册 已弃用,仅为向后兼容不支持 Client ID Metadata Documents 的授权服务器而保留。

  4. MCP 服务器 MUST 实现 OAuth 2.0 Protected Resource Metadata(RFC9728 )。MCP 客户端 MUST 使用 OAuth 2.0 Protected Resource Metadata 进行授权服务器发现 。

  5. MCP 授权服务器 MUST 至少提供以下一种发现机制:

    MCP 客户端 MUST 支持这两种发现机制 ,以获取与授权服务器交互所需的信息。

授权服务器发现

MCP 服务器通过 OAuth 2.0 Protected Resource Metadata 公布关联的授权服务器,MCP 客户端则通过授权服务器元数据发现来确定授权服务器端点和受支持的能力。实现 MUST 遵循授权服务器发现 中定义的规范性发现要求。

客户端注册

在发起授权流程前,MCP 客户端 MUST 按照客户端注册 中定义的要求和选择优先级,通过以下三种注册机制之一获取 client ID:Client ID Metadata Documents、预注册或动态客户端注册。

Scope 选择策略

MCP 服务器 SHOULD 按照 RFC 6750 第 3 节 的定义,在 WWW-Authenticate Header 中包含 scope 参数,以指明访问资源所需的 scope。这能够立即指导客户端在授权期间请求适当的 scope,遵循最小权限原则,并防止客户端请求过多权限。

WWW-Authenticate 质询中包含的 scope MAY 与 scopes_supported 相同,可以是其子集或超集,也可以是既非严格子集也非超集的另一组 scope。客户端 MUST NOT 假定质询 scope 集与 scopes_supported 之间存在任何特定集合关系。客户端 MUST 将质询中提供的 scope 视为当前操作的权威要求。这些 scope 是满足当前请求所必需的。重新授权时,客户端 SHOULD 将这些 scope 与此前已授予的 scope 一并包含,以免失去其他操作所需的权限(参见权限提升授权流程 )。服务器 SHOULD 力求采用一致的 scope 集构造方式,但不要求通过 scopes_supported 公开每个动态签发的 scope。

以下是带 scope 指引的 401 响应示例:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                         scope="files:read"

实现授权流程时,MCP 客户端 SHOULD 遵循最小权限原则,只请求预期操作所需的 scope。在初始授权握手期间,MCP 客户端 SHOULD 按以下优先级选择 scope:

  1. 如果初始 401 响应的 WWW-Authenticate Header 提供了 scope 参数,则使用该参数
  2. 如果 scope 不可用,则使用受保护资源元数据文档中 scopes_supported 定义的全部 scope;如果未定义 scopes_supported,则省略 scope 参数。

scopes_supported 字段用于表示基本功能所需的最小 scope 集(参见 Scope 最小化(英文) ),其他 scope 则通过 Scope 质询处理 一节所述的权限提升授权流程逐步请求。

授权流程步骤

流程图中的注册步骤使用客户端注册 所定义的机制之一。

完整授权流程如下:

  sequenceDiagram
    participant B as User-Agent (Browser)
    participant C as Client
    participant M as MCP Server (Resource Server)
    participant A as Authorization Server

    C->>M: MCP request without token
    M->>C: HTTP 401 Unauthorized with WWW-Authenticate header
    Note over C: Extract resource_metadata URL from WWW-Authenticate

    C->>M: Request Protected Resource Metadata
    M->>C: Return metadata

    Note over C: Parse metadata and extract authorization server(s)<br/>Client determines AS to use

    C->>A: GET Authorization server metadata endpoint
    Note over C,A: Try OAuth 2.0 and OpenID Connect<br/>discovery endpoints in priority order
    A-->>C: Authorization server metadata

    alt Client ID Metadata Documents
        Note over C: Client uses HTTPS URL as client_id
        Note over A: Server detects URL-formatted client_id
        A->>C: Fetch metadata from client_id URL
        C-->>A: JSON metadata document
        Note over A: Validate metadata and redirect_uris
    else Dynamic client registration
        C->>A: POST /register
        A->>C: Client Credentials
    else Pre-registered client
        Note over C: Use existing client_id
    end

    Note over C: Generate PKCE parameters<br/>Include resource parameter<br/>Apply scope selection strategy<br/>Record expected issuer
    C->>B: Open browser with authorization URL + code_challenge + resource
    B->>A: Authorization request with resource parameter
    Note over A: User authorizes
    A->>B: Redirect to callback with authorization code + iss
    B->>C: Authorization code callback
    Note over C: Validate iss against recorded issuer (RFC 9207)
    C->>A: Token request + code_verifier + resource
    A->>C: Access token (+ refresh token)
    C->>M: MCP request with access token
    M-->>C: MCP response
    Note over C,M: MCP communication continues with valid token

授权响应验证

在重定向用户代理之前,客户端 MUST 记录所选授权服务器已验证元数据文档中的 issuer 值(参见授权服务器元数据发现 ),并将其与用于存储 PKCE code verifier(以及使用时的 state 值)的同一份单次请求记录关联。本节的验证依赖该记录值的真实性;如果预期 issuer 来自未经验证的来源,本节机制不提供任何保护。

MCP 授权服务器 SHOULD 按照 RFC9207 第 2 节 的定义,在授权响应(包括错误响应)中包含 iss 参数。包含 iss 参数的授权服务器 MUST 在其元数据中将 authorization_response_iss_parameter_supported 设置为 true,以公布该能力(RFC9207 第 2.3 节 )。

收到授权响应后,MCP 客户端在向任何 token endpoint 发送授权码之前,MUST 按照 RFC9207 第 2.4 节 执行以下验证:

authorization_response_iss_parameter_supported响应中的 iss客户端操作
true存在使用简单字符串比较与记录的 issuer 进行比较(RFC3986 第 6.2.1 节 )
true缺失拒绝响应
false 或缺失存在使用简单字符串比较与记录的 issuer 进行比较(RFC3986 第 6.2.1 节 )
false 或缺失缺失继续

第三行应用 RFC9207 第 2.4 节 中的本地策略条款:无论元数据是否公布该能力,本规范都会将响应中存在的 iss 与记录的 issuer 进行比较,以兼容那些先发出 iss、之后才更新元数据的授权服务器。

本规范的未来修订预计会把授权服务器包含 iss 的要求从 SHOULD 升级为 MUST。建议实现者现在就发出并验证 iss,以简化该过渡;在相应修订定义升级路径之前,客户端因缺少 iss 而拒绝响应的行为仍由 authorization_response_iss_parameter_supported 决定。

客户端按照 RFC 9207 第 2.4 节 从 application/x-www-form-urlencoded 响应中解码 iss 值后,在比较前 MUST NOT 对 scheme 或 host 执行大小写折叠,也不得执行默认端口省略、尾部斜杠处理或百分号编码规范化(RFC 3986 第 6.2.2 至 6.2.3 节 )。

该验证同样适用于错误响应:出现不匹配时,客户端 MUST NOT 处理或显示 error、error_description 或 error_uri。

资源参数实现

MCP 客户端 MUST 按照 RFC 8707 的定义实现 Resource Indicators for OAuth 2.0,以明确指定令牌请求所针对的目标资源。resource 参数:

  1. MUST 同时包含在授权请求和令牌请求中。
  2. MUST 标识客户端打算使用该令牌访问的 MCP 服务器。
  3. MUST 使用 RFC 8707 第 2 节 定义的 MCP 服务器 canonical URI。

Canonical 服务器 URI

在本规范中,MCP 服务器的 canonical URI 定义为 RFC 8707 第 2 节 规定的资源标识符,并与 RFC 9728 中的 resource 参数保持一致。

MCP 客户端 SHOULD 按照 RFC 8707 的指导,为其打算访问的 MCP 服务器提供尽可能具体的 URI。尽管 canonical 形式使用小写 scheme 和 host 组件,实现仍 SHOULD 接受大写的 scheme 和 host 组件,以增强健壮性与互操作性。

有效 canonical URI 示例:

  • https://mcp.example.com/mcp
  • https://mcp.example.com
  • https://mcp.example.com:8443
  • https://mcp.example.com/server/mcp(当路径组件是标识单个 MCP 服务器所必需时)

无效 canonical URI 示例:

  • mcp.example.com(缺少 scheme)
  • https://mcp.example.com#fragment(包含 fragment)

注意: 根据 RFC 3986 ,https://mcp.example.com/(带尾部斜杠)和 https://mcp.example.com(不带尾部斜杠)在技术上都是有效的绝对 URI;但为获得更好的互操作性,除非尾部斜杠对特定资源具有语义意义,否则实现 SHOULD 始终使用不带尾部斜杠的形式。

例如,访问位于 https://mcp.example.com 的 MCP 服务器时,授权请求应包含:

&resource=https%3A%2F%2Fmcp.example.com

无论授权服务器是否支持该参数,MCP 客户端都 MUST 发送它。

访问令牌使用

令牌要求

向 MCP 服务器发出请求时,访问令牌的处理 MUST 符合 OAuth 2.1 第 5 节“Resource Requests” 定义的要求。具体而言:

  1. MCP 客户端 MUST 使用 OAuth 2.1 第 5.1.1 节 定义的 Authorization request header field:
Authorization: Bearer <access-token>

请注意,从客户端到服务器的每个 HTTP 请求都 MUST 包含 authorization。

  1. 访问令牌 MUST NOT 包含在 URI 查询字符串中

请求示例:

GET /mcp HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...

令牌处理

作为 OAuth 2.1 资源服务器的 MCP 服务器,MUST 按照 OAuth 2.1 第 5.2 节 的说明验证访问令牌。MCP 服务器 MUST 根据 RFC 8707 第 2 节 验证访问令牌是以自身为预期受众专门签发的。如果验证失败,服务器 MUST 按照 OAuth 2.1 第 5.3 节 的错误处理要求作出响应。无效或过期的令牌 MUST 收到 HTTP 401 响应。

MCP 客户端 MUST NOT 向 MCP 服务器发送并非由该 MCP 服务器授权服务器签发的令牌。

MCP 服务器 MUST 仅接受对其自身资源有效的令牌。

MCP 服务器 MUST NOT 接受或转发任何其他令牌。

刷新令牌

本节为 MCP 客户端和 MCP 服务器处理或签发 OAuth 与 OpenID Connect 刷新令牌提供指导。

需要刷新令牌的 MCP 客户端:

  • MUST 按照 OAuth 2.1 第 4.3 节 的规定,在传输和存储过程中对刷新令牌保密
  • SHOULD 在其 grant_types 客户端元数据中包含 refresh_token
  • 当授权服务器元数据的 scopes_supported 中包含该值时,MAY 将 offline_access 添加到授权请求和令牌请求的 scope 参数中
  • MUST NOT 假定授权服务器一定会签发刷新令牌;是否签发由 AS 自行决定

MCP 服务器(受保护资源)SHOULD NOT 在 WWW-Authenticate scope 或受保护资源元数据的 scopes_supported 中包含 offline_access,因为刷新令牌不是资源要求。

错误处理

服务器 MUST 为授权错误返回适当的 HTTP 状态码:

状态码描述用途
401Unauthorized需要授权或令牌无效
403Forbiddenscope 无效或权限不足
400Bad Request授权请求格式错误

Scope 质询处理

本节介绍客户端已有令牌但在运行时操作中需要额外权限时,如何处理 scope 不足错误。该流程遵循 OAuth 2.1 第 5 节 定义的错误处理模式,并利用 RFC 9728(OAuth 2.0 Protected Resource Metadata) 中的元数据字段。

运行时 Scope 不足错误

客户端在运行时操作中使用 scope 不足的访问令牌发出请求时,服务器 SHOULD 返回:

  • HTTP 403 Forbidden 状态码(依据 RFC 6750 第 3.1 节 )
  • 使用 Bearer scheme 并包含以下附加参数的 WWW-Authenticate Header:
    • error="insufficient_scope":指明具体的授权失败类型
    • scope="required_scope1 required_scope2":指定操作所需的最小 scope
    • resource_metadata:受保护资源元数据文档的 URI(与 401 响应保持一致)
    • error_description(可选):便于人类理解的错误说明

服务器 Scope 管理:服务器以 scope 不足错误响应时,SHOULD 按照 RFC 6750 第 3.1 节 ,在 scope 参数中包含满足当前操作所需的 scope。scope 属性描述访问所请求资源所需的 scope;服务器不必包含客户端此前已获授的 scope。

无论服务器采用何种 scope 包含策略,服务器 SHOULD 在一次质询中包含当前操作所需的全部 scope。增量质询(先返回一个缺失 scope,随后重试时再返回另一个)会迫使单个操作经历多轮授权往返,降低用户体验。所需 scope 可以根据具体请求参数和上下文动态确定,但一旦确定,就应一并发出。

服务器 SHOULD 采用一致的 scope 包含策略,为客户端提供可预测的行为。

服务器决定响应中包含哪些 scope 时,SHOULD 考虑对用户体验的影响,因为错误配置的 scope 可能要求用户频繁交互。

跨操作累积 scope 是客户端的责任。scope 合并要求参见权限提升授权流程 。

scope 不足响应示例:

HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
                         scope="files:write",
                         resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                         error_description="File write permission required for this operation"

权限提升授权流程

客户端会在初始授权期间或运行时收到与 scope 有关的错误(insufficient_scope)。客户端 SHOULD 通过权限提升授权流程请求具有更大 scope 集的新访问令牌,或以其他适当方式处理这些错误。代表用户操作的客户端 SHOULD 尝试权限提升授权流程。代表自身操作的客户端(client_credentials 客户端)MAY 尝试权限提升授权流程,或立即中止请求。

流程如下:

  1. 从授权服务器响应或 WWW-Authenticate Header 中解析错误信息
  2. 通过合并客户端此前请求的 scope 集与当前质询中的 scope,确定所需 scope。这能确保服务器按照 RFC 6750 第 3.1 节 发出每个操作的 scope 质询时,保留此前已经授予的权限。客户端 MAY 另外参考 Scope 选择策略 ,了解初始 scope 的选择指导。
  3. 使用确定的 scope 集发起(重新)授权
  4. 使用新授权重试原始请求,重试次数不得超过少数几次;超过后将其视为永久授权失败

客户端 SHOULD 实现重试限制,并且 SHOULD 跟踪 scope 提升尝试,避免相同资源与操作组合反复失败。

服务器判断令牌是否足以执行某项操作时,MUST 考虑 scope 层级关系,即更宽泛的 scope 蕴含更窄的 scope。

安全注意事项

本规范的实现 MUST 遵循安全注意事项 中的规范性安全要求,其中涵盖令牌受众绑定与验证、令牌窃取、通信安全、授权码保护、mix-up 与 confused deputy 攻击、开放重定向,以及 Client ID Metadata Document 安全性。

MCP 授权扩展

核心协议包含若干定义附加授权机制的授权扩展。这些扩展具有以下特征:

  • 可选:实现可以选择采用这些扩展
  • 增量:扩展不会修改或破坏核心协议功能;它们在保持核心协议行为的同时增加新能力
  • 可组合:扩展采用模块化设计,可以无冲突地协同工作,使实现能够同时采用多个扩展
  • 独立版本化:扩展遵循 MCP 核心版本周期,但可根据需要采用独立版本

支持的扩展列表可在 MCP Authorization Extensions 仓库中找到。