> ## Documentation Index
> Fetch the complete documentation index at: https://mcp.zhcndoc.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 授权

<div id="enable-section-numbers" />

## 引言

### 目的与范围

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

### 协议要求

授权对于 MCP 实现来说是 **可选的** 。当支持授权时：

* 使用基于 HTTP 传输的实现 **应该** 符合本规范。
* 使用 STDIO 传输的实现 **不应该** 遵循本规范，而
  应从环境中检索凭证。
* 使用替代传输的实现 **必须** 遵循其协议既定的安全最佳
  实践。

### 标准合规性

此授权机制基于以下列出的既定规范，但
实现了其功能的选定子集，以确保安全性和互操作性
同时保持简单性：

* OAuth 2.1 IETF DRAFT ([draft-ietf-oauth-v2-1-13](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13))
* OAuth 2.0 授权服务器元数据
  ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414))
* OAuth 2.0 动态客户端注册协议
  ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591))
* OAuth 2.0 受保护资源元数据 ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728))
* OAuth 客户端 ID 元数据文档 ([draft-ietf-oauth-client-id-metadata-document-00](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00))

## 角色

受保护的 *MCP 服务器* 充当 [OAuth 2.1 资源服务器](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-13.html#name-roles)，
能够使用访问令牌接受和响应受保护的资源请求。

*MCP 客户端* 充当 [OAuth 2.1 客户端](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-13.html#name-roles)，
代表资源所有者发出受保护的资源请求。

*授权服务器* 负责与用户交互（如有必要）并为在 MCP 服务器上使用颁发访问令牌。
授权服务器的实现细节超出了本规范的范围。它可以与
资源服务器一起托管，也可以是单独的实体。[授权服务器发现部分](#authorization-server-discovery)
规定了 MCP 服务器如何向客户端指示其对应授权服务器的位置。

## 概述

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

2. 授权服务器和 MCP 客户端 **应该** 支持 OAuth 客户端 ID 元数据文档
   ([draft-ietf-oauth-client-id-metadata-document-00](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00))。

3. 授权服务器和 MCP 客户端 **可以** 支持 OAuth 2.0 动态客户端注册
   协议 ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591))。

4. MCP 服务器 **必须** 实施 OAuth 2.0 受保护资源元数据 ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728))。
   MCP 客户端 **必须** 使用 OAuth 2.0 受保护资源元数据进行授权服务器发现。

5. MCP 授权服务器 **必须** 提供以下至少一种发现机制：

   * OAuth 2.0 授权服务器元数据 ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414))
   * [OpenID Connect Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)

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

## 授权服务器发现

本节描述了 MCP 服务器向其关联的
授权服务器通告给 MCP 客户端的机制，以及 MCP
客户端可以确定授权服务器端点和支持能力的发现过程。

### 授权服务器位置

MCP 服务器 **必须** 实施 OAuth 2.0 受保护资源元数据 ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728))
规范以指示授权服务器的位置。MCP 服务器返回的受保护资源元数据文档 **必须** 包含
`authorization_servers` 字段，其中包含至少一个授权服务器。

`authorization_servers` 的具体使用超出了本规范的范围；实施者应咨询
OAuth 2.0 受保护资源元数据 ([RFC9728](https://datatracker.ietf.org/doc/html/rfc9728)) 以
获取实施细节的指导。

实施者应注意，受保护资源元数据文档可以定义多个授权服务器。选择使用哪个授权服务器的责任在于 MCP 客户端，遵循
[RFC9728 第 7.6 节 "授权服务器"](https://datatracker.ietf.org/doc/html/rfc9728#name-authorization-servers) 中指定的指南。

### 受保护资源元数据发现要求

MCP 服务器 **必须** 实施以下一种发现机制，以向 MCP 客户端提供授权服务器位置信息：

1. **WWW-Authenticate Header**：如 [RFC9728 第 5.1 节](https://datatracker.ietf.org/doc/html/rfc9728#name-www-authenticate-response) 所述，在返回 `401 Unauthorized` 响应时，在 `WWW-Authenticate` HTTP  header 的 `resource_metadata` 下包含资源元数据 URL。

2. **Well-Known URI**：如 [RFC9728](https://datatracker.ietf.org/doc/html/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`  headers 中的资源元数据 URL；否则，它们 **必须** 回退到按上述顺序构建和请求知名 URI。

MCP 服务器 **应该** 在 `WWW-Authenticate`  header 中包含 `scope` 参数，如
[RFC 6750 第 3 节](https://datatracker.ietf.org/doc/html/rfc6750#section-3) 所定义，
以指示访问资源所需的权限范围。这为客户提供了即时
指导，以便在授权期间请求适当的权限范围，
遵循最小权限原则并防止客户端请求过多的权限。

`WWW-Authenticate` 质询中包含的权限范围 **可以** 匹配 `scopes_supported`，是其子集
或超集，或者是既不是严格子集也不是
超集的替代集合。客户端 **不得** 假设质询的
权限范围集与 `scopes_supported` 之间存在任何特定的集合关系。客户端 **必须** 将质询中提供的权限范围视为满足当前请求的权威依据。服务器 **应该** 努力保持
构建权限范围集的一致性，但它们不需要通过 `scopes_supported` 表面化每个动态
颁发的权限范围。

带有权限范围指导的 401 响应示例：

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

MCP 客户端 **必须** 能够解析 `WWW-Authenticate`  headers 并适当响应来自 MCP 服务器的 `HTTP 401 Unauthorized` 响应。

如果 `scope` 参数不存在，客户端 **应该** 应用 [权限范围选择策略](#scope-selection-strategy) 部分中定义的回退行为。

### 授权服务器元数据发现

为了处理不同的颁发者 URL 格式并确保与 OAuth 2.0 授权服务器元数据和 OpenID Connect Discovery 1.0 规范的互操作性，MCP 客户端在发现授权服务器元数据时 **必须** 尝试多个知名端点。

发现方法基于 [RFC8414 第 3.1 节 "授权服务器元数据请求"](https://datatracker.ietf.org/doc/html/rfc8414#section-3.1) 用于 OAuth 2.0 授权服务器元数据发现，以及 [RFC8414 第 5 节 "兼容性说明"](https://datatracker.ietf.org/doc/html/rfc8414#section-5) 用于 OpenID Connect Discovery 1.0 互操作性。

对于带有路径组件的颁发者 URL（例如 `https://auth.example.com/tenant1`），客户端 **必须** 按以下优先级顺序尝试端点：

1. 带路径插入的 OAuth 2.0 授权服务器元数据：`https://auth.example.com/.well-known/oauth-authorization-server/tenant1`
2. 带路径插入的 OpenID Connect Discovery 1.0：`https://auth.example.com/.well-known/openid-configuration/tenant1`
3. 追加路径的 OpenID Connect Discovery 1.0：`https://auth.example.com/tenant1/.well-known/openid-configuration`

对于没有路径组件的颁发者 URL（例如 `https://auth.example.com`），客户端 **必须** 尝试：

1. OAuth 2.0 授权服务器元数据：`https://auth.example.com/.well-known/oauth-authorization-server`
2. OpenID Connect Discovery 1.0：`https://auth.example.com/.well-known/openid-configuration`

### 授权服务器发现序列图

下图概述了一个示例流程：

```mermaid theme={null}
sequenceDiagram
    participant C as 客户端
    participant M as MCP 服务器 (资源服务器)
    participant A as 授权服务器

    Note over C: 尝试未认证的 MCP 请求
    C->>M: 不带令牌的 MCP 请求
    M-->>C: HTTP 401 Unauthorized (可能包含 WWW-Authenticate header)

    alt Header 包含 resource_metadata
        Note over C: 从 header 中提取 resource_metadata URL
        C->>M: GET resource_metadata URI
        M-->>C: 包含授权服务器 URL 的资源元数据
    else Header 中无 resource_metadata
        Note over C: 回退到 well-known URI 探测
        Note over M: _如果 MCP 服务器位于根路径则不适用_
        C->>M: GET /.well-known/oauth-protected-resource/mcp
        alt 找到子路径元数据
            M-->>C: 包含授权服务器 URL 的资源元数据
        else 未找到子路径
            C->>M: GET /.well-known/oauth-protected-resource
            alt 找到根元数据
                M-->>C: 包含授权服务器 URL 的资源元数据
            else 未找到根元数据
                Note over C: 中止或使用预配置值
            end
        end
    end

    Note over C: 验证 RS 元数据，<br />构建 AS 元数据 URL

    C->>A: GET 授权服务器元数据端点
    Note over C,A: 按优先级尝试 OAuth 2.0 和 OpenID Connect<br/>发现端点
    A-->>C: 授权服务器元数据

    Note over C,A: OAuth 2.1 授权流程在此发生

    C->>A: 令牌请求
    A-->>C: 访问令牌

    C->>M: 带访问令牌的 MCP 请求
    M-->>C: MCP 响应
    Note over C,M: MCP 通信继续使用有效令牌进行
```

## 客户端注册方法

MCP 支持三种客户端注册机制。请根据您的场景选择：

* **客户端 ID 元数据文档**：当客户端和服务器之间没有预先存在的关系时（最常见）
* **预注册**：当客户端和服务器之间已存在关系时
* **动态客户端注册**：用于向后兼容性或特定要求

支持所有选项的客户端 **应 (SHOULD)** 遵循以下优先级顺序：

1. 如果客户端可用，使用服务器的预注册客户端信息
2. 如果授权服务器表明支持该功能（通过 OAuth 授权服务器元数据中的 `client_id_metadata_document_supported`），则使用客户端 ID 元数据文档
3. 如果授权服务器支持（通过 OAuth 授权服务器元数据中的 `registration_endpoint`），则使用动态客户端注册作为后备方案
4. 如果没有其他选项可用，提示用户输入客户端信息

### 客户端 ID 元数据文档

MCP 客户端和授权服务器 **应 (SHOULD)** 支持 [OAuth 客户端 ID 元数据文档](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00) 中规定的 OAuth 客户端 ID 元数据文档。
这种方法允许客户端使用 HTTPS URL 作为客户端标识符，其中 URL 指向包含客户端元数据的 JSON 文档。这解决了服务器和客户端没有预先存在关系的常见 MCP 场景。

#### 实现要求

支持客户端 ID 元数据文档的 MCP 实现 **必须 (MUST)** 遵循 [OAuth 客户端 ID 元数据文档](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00) 中规定的要求。
关键要求包括：

**对于 MCP 客户端：**

* 客户端 **必须 (MUST)** 按照 RFC 要求将元数据文档托管在 HTTPS URL 上
* `client_id` URL **必须 (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 节](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6.2) 中描述的适当 JWKS 配置

**对于授权服务器：**

* **应 (SHOULD)** 在遇到 URL 格式的 client\_ids 时获取元数据文档
* **必须 (MUST)** 验证获取的文档的 `client_id` 与 URL 完全匹配
* **应 (SHOULD)** 缓存元数据并遵守 HTTP 缓存头
* **必须 (MUST)** 针对元数据文档中的内容验证授权请求中提供的重定向 URI
* **必须 (MUST)** 验证文档结构是有效的 JSON 并包含必需字段
* **应 (SHOULD)** 遵循 [客户端 ID 元数据文档第 6 节](https://www.ietf.org/archive/id/draft-ietf-oauth-client-id-metadata-document-00.html#section-6) 中的安全注意事项

#### 元数据文档示例

```json theme={null}
{
  "client_id": "https://app.example.com/oauth/client-metadata.json",
  "client_name": "示例 MCP 客户端",
  "client_uri": "https://app.example.com",
  "logo_uri": "https://app.example.com/logo.png",
  "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"
}
```

#### 客户端 ID 元数据文档流程

下图说明了使用客户端 ID 元数据文档时的完整流程：

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Client as MCP 客户端
    participant Server as 授权服务器
    participant Metadata as 元数据端点<br/>(客户端的 HTTPS URL)
    participant Resource as MCP 服务器

    Note over Client,Metadata: 客户端托管元数据于<br/>https://app.example.com/oauth/metadata.json

    User->>Client: 发起与 MCP 服务器的连接
    Client->>Server: 授权请求<br/>client_id=https://app.example.com/oauth/metadata.json<br/>redirect_uri=http://localhost:3000/callback

    Server->>User: 身份验证提示
    User->>Server: 提供凭证
    Note over Server: 验证用户

    Note over Server: 检测到 URL 格式的 client_id

    Server->>Metadata: GET https://app.example.com/oauth/metadata.json
    Metadata-->>Server: JSON 元数据文档<br/>{client_id, client_name, redirect_uris, ...}

    Note over Server: 验证：<br/>1. client_id 与 URL 匹配<br/>2. redirect_uri 在允许列表中<br/>3. 文档结构有效<br/>4. (可选) 域通过信任策略允许

    alt 验证成功
        Server->>User: 显示带有 client_name 的同意页面
        User->>Server: 批准访问
        Server->>Client: 通过 redirect_uri 返回授权码
        Client->>Server: 交换代码以获取令牌<br/>client_id=https://app.example.com/oauth/metadata.json
        Server-->>Client: 访问令牌
        Client->>Resource: 带有访问令牌的 MCP 请求
        Resource-->>Client: MCP 响应
    else 验证失败
        Server->>User: 错误响应<br/>error=invalid_client 或 invalid_request
    end

    Note over Server: 缓存元数据以供未来请求<br/>(遵守 HTTP 缓存头)
```

#### 发现

授权服务器通过在其 OAuth 授权服务器元数据中包含以下属性来宣传它们支持使用客户端 ID 元数据文档的客户端：

```json theme={null}
{
  "client_id_metadata_document_supported": true
}
```

MCP 客户端 **应 (SHOULD)** 检查此功能，如果不可用，**可以 (MAY)** 回退到动态客户端注册
或预注册。

### 预注册

MCP 客户端 **应 (SHOULD)** 支持静态客户端凭证选项，例如由预注册流程提供的凭证。这可以是：

1. 硬编码客户端 ID（以及适用的客户端凭证），专门供 MCP 客户端在与该授权服务器交互时使用，或
2. 向用户展示一个界面，允许他们在自己注册 OAuth 客户端后输入这些详细信息（例如，通过服务器托管的配置界面）。

### 动态客户端注册

MCP 客户端和授权服务器 **可以 (MAY)** 支持
OAuth 2.0 动态客户端注册协议 [RFC7591](https://datatracker.ietf.org/doc/html/rfc7591)
以允许 MCP 客户端无需用户交互即可获取 OAuth 客户端 ID。
包含此选项是为了与早期版本的 MCP 授权规范保持向后兼容性。

## 权限范围选择策略

在实现授权流程时，MCP 客户端 **应 (SHOULD)** 遵循最小权限原则，仅请求其预期操作所需的权限范围。在初始授权握手期间，MCP 客户端
**应 (SHOULD)** 遵循以下权限范围选择优先级顺序：

1. **使用 `scope` 参数** 来自 401 响应中初始 `WWW-Authenticate` 头（如果提供）
2. **如果 `scope` 不可用**，使用受保护资源元数据文档中 `scopes_supported` 定义的所有权限范围，如果 `scopes_supported` 未定义，则省略 `scope` 参数。

这种方法适应了 MCP 客户端的通用性质，它们通常缺乏特定领域的知识来对单个权限范围选择做出明智的决定。请求所有可用权限范围允许授权服务器和最终用户在同意过程中确定适当的权限。

这种方法在遵循最小权限原则的同时最大限度地减少了用户摩擦。
`scopes_supported` 字段旨在表示基本功能所需的最小权限范围集
（参见 [权限范围最小化](/specification/2025-11-25/basic/security_best_practices#scope-minimization)），
附加权限范围通过 [权限范围挑战处理](#scope-challenge-handling) 部分中描述的逐步授权流程步骤增量请求。

## 授权流程步骤

完整的授权流程如下所示：

```mermaid theme={null}
sequenceDiagram
    participant B as 用户代理 (浏览器)
    participant C as 客户端
    participant M as MCP 服务器 (资源服务器)
    participant A as 授权服务器

    C->>M: 无令牌的 MCP 请求
    M->>C: HTTP 401 未授权，带有 WWW-Authenticate 头
    Note over C: 从 WWW-Authenticate 提取 resource_metadata URL

    C->>M: 请求受保护资源元数据
    M->>C: 返回元数据

    Note over C: 解析元数据并提取授权服务器<br/>客户端确定要使用的 AS

    C->>A: GET 授权服务器元数据端点
    Note over C,A: 尝试 OAuth 2.0 和 OpenID Connect<br/>按优先级顺序发现端点
    A-->>C: 授权服务器元数据

    alt 客户端 ID 元数据文档
        Note over C: 客户端使用 HTTPS URL 作为 client_id
        Note over A: 服务器检测到 URL 格式的 client_id
        A->>C: 从 client_id URL 获取元数据
        C-->>A: JSON 元数据文档
        Note over A: 验证元数据和 redirect_uris
    else 动态客户端注册
        C->>A: POST /register
        A->>C: 客户端凭证
    else 预注册客户端
        Note over C: 使用现有 client_id
    end

    Note over C: 生成 PKCE 参数<br/>包含 resource 参数<br/>应用权限范围选择策略
    C->>B: 打开浏览器携带授权 URL + code_challenge + resource
    B->>A: 带有 resource 参数的授权请求
    Note over A: 用户授权
    A->>B: 重定向到回调并携带授权码
    B->>C: 授权码回调
    C->>A: 令牌请求 + code_verifier + resource
    A->>C: 访问令牌 (+ 刷新令牌)
    C->>M: 带有访问令牌的 MCP 请求
    M-->>C: MCP 响应
    Note over C,M: MCP 通信继续使用有效令牌
```

## 资源参数实现

MCP 客户端**必须**实现 [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) 中定义的 OAuth 2.0 资源指示器，以明确指定请求令牌的目标资源。`resource` 参数：

1. **必须**包含在授权请求和令牌请求中。
2. **必须**标识客户端打算使用该令牌的 MCP 服务器。
3. **必须**使用 [RFC 8707 第 2 节](https://www.rfc-editor.org/rfc/rfc8707.html#name-access-token-request) 中定义的 MCP 服务器的规范 URI。

### 规范服务器 URI

就本规范而言，MCP 服务器的规范 URI 定义为 [RFC 8707 第 2 节](https://www.rfc-editor.org/rfc/rfc8707.html#section-2) 中指定的资源标识符，并与 [RFC 9728](https://datatracker.ietf.org/doc/html/rfc9728) 中的 `resource` 参数保持一致。

MCP 客户端**应该**为其打算访问的 MCP 服务器提供尽可能具体的 URI，遵循 [RFC 8707](https://www.rfc-editor.org/rfc/rfc8707) 中的指导。虽然规范形式使用小写的方案和主机组件，但为了健壮性和互操作性，实现**应该**接受大写的方案和主机组件。

有效规范 URI 示例：

* `https://mcp.example.com/mcp`
* `https://mcp.example.com`
* `https://mcp.example.com:8443`
* `https://mcp.example.com/server/mcp`（当需要路径组件来标识单个 MCP 服务器时）

无效规范 URI 示例：

* `mcp.example.com`（缺少方案）
* `https://mcp.example.com#fragment`（包含片段）

> **注意：** 虽然根据 [RFC 3986](https://www.rfc-editor.org/rfc/rfc3986)，`https://mcp.example.com/`（带尾随斜杠）和 `https://mcp.example.com`（不带尾随斜杠）在技术上都是有效的绝对 URI，但除非尾随斜杠对特定资源具有语义意义，否则实现**应该**一致地使用不带尾随斜杠的形式以获得更好的互操作性。

例如，如果访问 `https://mcp.example.com` 处的 MCP 服务器，授权请求将包括：

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

无论授权服务器是否支持，MCP 客户端**必须**发送此参数。

## 访问令牌使用

### 令牌要求

向 MCP 服务器发出请求时的访问令牌处理**必须**符合 [OAuth 2.1 第 5 节“资源请求”](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-5) 中定义的要求。
具体而言：

1. MCP 客户端**必须**使用 [OAuth 2.1 第 5.1.1 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-5.1.1) 中定义的 Authorization 请求头字段：

```
Authorization: Bearer <access-token>
```

请注意，授权**必须**包含在从客户端到服务器的每个 HTTP 请求中，即使它们是同一逻辑会话的一部分。

2. 访问令牌**不得**包含在 URI 查询字符串中

请求示例：

```http theme={null}
GET /mcp HTTP/1.1
Host: mcp.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
```

### 令牌处理

MCP 服务器作为 OAuth 2.1 资源服务器，**必须**按照 [OAuth 2.1 第 5.2 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-5.2) 中所述验证访问令牌。
MCP 服务器**必须**验证访问令牌是专门为其作为预期受众颁发的，根据 [RFC 8707 第 2 节](https://www.rfc-editor.org/rfc/rfc8707.html#section-2)。
如果验证失败，服务器**必须**根据 [OAuth 2.1 第 5.3 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-5.3) 错误处理要求进行响应。无效或过期的令牌**必须**收到 HTTP 401 响应。

MCP 客户端**不得**向 MCP 服务器发送除 MCP 服务器授权服务器颁发的令牌以外的令牌。

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

MCP 服务器**不得**接受或传输任何其他令牌。

## 错误处理

服务器**必须**为授权错误返回适当的 HTTP 状态码：

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

### Scope 挑战处理

本节涵盖运行时操作中当客户端已拥有令牌但需要额外权限时处理权限不足错误的情况。这遵循 [OAuth 2.1 第 5 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-5) 中定义的错误处理模式，并利用 [RFC 9728 (OAuth 2.0 受保护资源元数据)](https://datatracker.ietf.org/doc/html/rfc9728) 中的元数据字段。

#### 运行时权限不足错误

当客户端在运行时操作中使用权限不足的访问令牌发出请求时，服务器**应该**响应：

* `HTTP 403 Forbidden` 状态码（根据 [RFC 6750 第 3.1 节](https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)）
* 带有 `Bearer` 方案和附加参数的 `WWW-Authenticate` 头：
  * `error="insufficient_scope"` - 指示特定类型的授权失败
  * `scope="required_scope1 required_scope2"` - 指定操作所需的最小 scope
  * `resource_metadata` - 受保护资源元数据文档的 URI（与 401 响应保持一致）
  * `error_description`（可选）- 错误的人类可读描述

**服务器 Scope 管理**：当响应权限不足错误时，服务器**应该**在 `scope` 参数中包含满足当前请求所需的 scope。

服务器在确定包含哪些 scope 方面具有灵活性：

* **最小方法**：包含特定操作新需要的 scope。如果现有已授予的 scope 也是必需的，也包含它们，以防止客户端丢失先前授予的权限。
* **推荐方法**：包含现有相关 scope 和新需要的 scope，以防止客户端丢失先前授予的权限
* **扩展方法**：包含现有 scope、新需要的 scope 以及通常一起使用的相关 scope

选择取决于服务器对用户体验影响和授权摩擦的评估。

服务器**应该**在其 scope 包含策略上保持一致，以为客户端提供可预测的行为。

服务器在确定响应中包含哪些 scope 时**应该**考虑用户体验影响，因为配置错误的 scope 可能需要频繁的用户交互。

权限不足响应示例：

```http theme={null}
HTTP/1.1 403 Forbidden
WWW-Authenticate: Bearer error="insufficient_scope",
                         scope="files:read files:write user:profile",
                         resource_metadata="https://mcp.example.com/.well-known/oauth-protected-resource",
                         error_description="Additional file write permission required"
```

#### 升级授权流程

客户端将在初始授权或运行时收到与 scope 相关的错误（`insufficient_scope`）。
客户端**应该**通过升级授权流程请求具有增加的一组 scope 的新访问令牌来响应这些错误，或以其他适当方式处理错误。
代表用户行事的客户端**应该**尝试升级授权流程。代表自己行事的客户端（`client_credentials` 客户端）**可以**尝试升级授权流程或立即中止请求。

流程如下：

1. **解析错误信息** 来自授权服务器响应或 `WWW-Authenticate` 头
2. **确定所需 scope** 如 [Scope 选择策略](#scope-selection-strategy) 中所述。
3. **发起（重新）授权** 使用确定的 scope 集
4. **重试原始请求** 使用新授权不超过几次，并将其视为永久授权失败

客户端**应该**实施重试限制，并**应该**跟踪 scope 升级尝试，以避免同一资源和操作组合的重复失败。

## 安全考虑

实现**必须**遵循 [OAuth 2.1 第 7. 节“安全考虑”](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#name-security-considerations) 中列出的 OAuth 2.1 安全最佳实践。

### 令牌受众绑定和验证

[RFC 8707](https://www.rfc-editor.org/rfc/rfc8707.html) 资源指示器通过将令牌绑定到其预期受众提供关键的安全益处，**当授权服务器支持该功能时**。为了启用当前和未来的采用：

* MCP 客户端**必须**在授权和令牌请求中包含 `resource` 参数，如 [资源参数实现](#资源参数实现) 节中指定
* MCP 服务器**必须**验证呈现给它们的令牌是专门为其使用颁发的

[安全最佳实践文档](/specification/2025-11-25/basic/security_best_practices#token-passthrough)
概述了为什么令牌受众验证至关重要，以及为什么明确禁止令牌透传。

### 令牌窃取

获得客户端存储的令牌，或服务器上缓存或记录的令牌的攻击者可以使用对资源服务器看似合法的请求访问受保护资源。

客户端和服务器**必须**实施安全的令牌存储并遵循 OAuth 最佳实践，
如 [OAuth 2.1，第 7.1 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-7.1) 中所述。

授权服务器**应该**颁发短期访问令牌以减少令牌泄露的影响。
对于公共客户端，授权服务器**必须**按照 [OAuth 2.1 第 4.3.1 节“令牌端点扩展”](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-4.3.1) 中所述轮换刷新令牌。

### 通信安全

实现**必须**遵循 [OAuth 2.1 第 1.5 节“通信安全”](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-1.5)。

具体而言：

1. 所有授权服务器端点**必须**通过 HTTPS 提供服务。
2. 所有重定向 URI **必须**是 `localhost` 或使用 HTTPS。

### 授权码保护

获得授权响应中包含的授权码的攻击者可以尝试兑换授权码以获取访问令牌或以其他方式使用授权码。
（在 [OAuth 2.1 第 7.5 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-7.5) 中进一步描述）

为了缓解这种情况，MCP 客户端**必须**根据 [OAuth 2.1 第 7.5.2 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-7.5.2) 实施 PKCE，并**必须**在进行授权之前验证 PKCE 支持。
PKCE 通过要求客户端创建秘密验证器 - 挑战对来帮助防止授权码拦截和注入攻击，确保只有原始请求者可以将授权码交换为令牌。

MCP 客户端在技术上能够时**必须**使用 `S256` 代码挑战方法，如 [OAuth 2.1 第 4.1.1 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-4.1.1) 所要求。

由于 OAuth 2.1 和 PKCE 规范未定义客户端发现 PKCE 支持的机制，MCP 客户端**必须**依赖授权服务器元数据来验证此功能：

* **OAuth 2.0 授权服务器元数据**：如果 `code_challenge_methods_supported` 不存在，则授权服务器不支持 PKCE，MCP 客户端**必须**拒绝继续。

* **OpenID Connect Discovery 1.0**：虽然 [OpenID 提供者元数据](https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata) 未定义 `code_challenge_methods_supported`，但 OpenID 提供者通常包含此字段。MCP 客户端**必须**验证提供者元数据响应中 `code_challenge_methods_supported` 的存在。如果该字段不存在，MCP 客户端**必须**拒绝继续。

提供 OpenID Connect Discovery 1.0 的授权服务器**必须**在其元数据中包含 `code_challenge_methods_supported` 以确保 MCP 兼容性。

### 开放重定向

攻击者可以制作恶意重定向 URI 将用户定向到钓鱼网站。

MCP 客户端**必须**向授权服务器注册重定向 URI。

授权服务器**必须**针对预注册值验证精确的重定向 URI 以防止重定向攻击。

MCP 客户端**应该**在授权码流程中使用和验证 state 参数，并丢弃任何不包含或与原始 state 不匹配的结果。

授权服务器**必须**采取预防措施防止将用户代理重定向到不可信的 URI，遵循 [OAuth 2.1 第 7.12.2 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-13#section-7.12.2) 中提出的建议

授权服务器**应该**仅在信任重定向 URI 时自动重定向用户代理。如果 URI 不可信，授权服务器可以通知用户并依赖用户做出正确的决定。

### 客户端 ID 元数据文档安全

在实施客户端 ID 元数据文档时，授权服务器**必须**考虑 [OAuth 客户端 ID 元数据文档，第 6 节](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00#name-security-considerations) 中详述的安全影响。
关键考虑因素包括：

#### 授权服务器滥用保护

授权服务器接受来自未知客户端的 URL 作为输入并获取该 URL。
恶意客户端可以使用此功能触发授权服务器向任意 URL 发出请求，
例如向授权服务器有权访问的私有管理端点发出请求。

获取元数据文档的授权服务器**应该**考虑 [服务器端请求伪造 (SSRF)](https://developer.mozilla.org/docs/Web/Security/Attacks/SSRF) 风险，如 [OAuth 客户端 ID 元数据文档：服务器端请求伪造 (SSRF) 攻击](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-00#name-server-side-request-forgery) 中所述。

#### Localhost 重定向 URI 风险

客户端 ID 元数据文档本身无法防止 `localhost` URL  impersonation。攻击者可以通过以下方式声称是任何客户端：

1. 提供合法客户端的元数据 URL 作为其 `client_id`
2. 绑定到任何 `localhost` 端口，并将该地址作为 redirect\_uri 提供
3. 当用户批准时通过重定向接收授权码

服务器将看到合法客户端的元数据文档，用户将看到合法客户端的名称，使得攻击检测变得困难。

授权服务器：

* **应该**为仅限 `localhost` 的重定向 URI 显示额外警告
* **可以**要求额外的证明机制以增强安全性
* **必须**在授权期间清楚显示重定向 URI 主机名

#### 信任策略

授权服务器**可以**实施基于域的信任策略：

* 受信任域的允许列表（用于受保护服务器）
* 接受任何 HTTPS `client_id`（用于开放服务器）
* 对未知域的信誉检查
* 基于域年龄或证书验证的限制
* 显著显示 CIMD 和其他关联客户端主机名以防止钓鱼

服务器对其访问策略保持完全控制。

### 混淆代理问题

攻击者可以利用作为第三方 API 中介的 MCP 服务器，导致 [混淆代理漏洞](/specification/2025-11-25/basic/security_best_practices#confused-deputy-problem)。
通过使用窃取的授权码，他们可以在未经用户同意的情况下获取访问令牌。

使用静态客户端 ID 的 MCP 代理服务器**必须**在转发到第三方授权服务器之前获得每个动态注册客户的用户同意（这可能需要额外的同意）。

### 访问令牌权限限制

如果服务器接受为其他资源颁发的令牌，攻击者可以获得未经授权的访问或以其他方式危害 MCP 服务器。

此漏洞有两个关键维度：

1. **受众验证失败。** 当 MCP 服务器不验证令牌是否专门为其意图颁发时（例如，通过受众声明，如 [RFC9068](https://www.rfc-editor.org/rfc/rfc9068.html) 中所述），它可能接受最初为其他服务颁发的令牌。这破坏了基本的 OAuth 安全边界，允许攻击者在不同于预期的不同服务之间重用合法令牌。
2. **令牌透传。** 如果 MCP 服务器不仅接受具有不正确受众的令牌，还将这些未修改的令牌转发给下游服务，它可能会导致 ["混淆代理"问题](#混淆代理问题)，其中下游 API 可能错误地信任令牌，好像它来自 MCP 服务器，或假设令牌已由上游 API 验证。有关更多详细信息，请参阅安全最佳实践指南的 [令牌透传部分](/specification/2025-11-25/basic/security_best_practices#token-passthrough)。

MCP 服务器**必须**在处理请求之前验证访问令牌，确保访问令牌是专门为 MCP 服务器颁发的，并采取所有必要步骤确保不向未经授权的方返回数据。

MCP 服务器**必须**遵循 [OAuth 2.1 - 第 5.2 节](https://www.ietf.org/archive/id/draft-ietf-oauth-v2-1-13.html#section-5.2) 中的指南来验证入站令牌。

MCP 服务器**必须**仅接受专门为其意图颁发的令牌，并**必须**拒绝未在受众声明中包含它们或以其他方式验证它们是令牌预期接收者的令牌。有关详细信息，请参阅 [安全最佳实践令牌透传部分](/specification/2025-11-25/basic/security_best_practices#token-passthrough)。

如果 MCP 服务器向上游 API 发出请求，它可以作为它们的 OAuth 客户端。在上游 API 使用的访问令牌是一个单独的令牌，由上游授权服务器颁发。MCP 服务器**不得**透传它从 MCP 客户端收到的令牌。

MCP 客户端**必须**实施并使用 [RFC 8707 - OAuth 2.0 资源指示器](https://www.rfc-editor.org/rfc/rfc8707.html) 中定义的 `resource` 参数，以明确指定请求令牌的目标资源。此要求与 [RFC 9728 第 7.4 节](https://datatracker.ietf.org/doc/html/rfc9728#section-7.4) 中的建议保持一致。这确保访问令牌绑定到其预期资源，并且不能在不同服务之间被滥用。

## MCP 授权扩展

核心协议有几个授权扩展，定义了额外的授权机制。这些扩展是：

* **可选** - 实现可以选择采用这些扩展
* **附加性** - 扩展不会修改或破坏核心协议功能；它们在保留核心协议行为的同时添加新功能
* **可组合** - 扩展是模块化的，旨在无冲突地协同工作，允许实现同时采用多个扩展
* **独立版本控制** - 扩展遵循核心 MCP 版本控制周期，但可以根据需要采用独立版本控制

支持的扩展列表可以在 [MCP 授权扩展](https://github.com/modelcontextprotocol/ext-auth) 仓库中找到。
