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

# MCP安全模型与OAuth 2.1认证

> MCP安全模型与OAuth 2.1认证机制全面详解，涵盖PKCE防截获授权验证流程、Dynamic Client Registration动态客户端注册、细粒度工具权限控制及HTTPS传输加密配置。帮助开发者在MCP Server中构建完善的身份认证与数据隐私保护方案

# 安全与认证

## 7.1 MCP安全模型

MCP的安全责任分布在不同层面：

| 层面       | 负责方                | 内容            |
| -------- | ------------------ | ------------- |
| **传输安全** | 传输层                | HTTPS加密、证书验证  |
| **身份认证** | OAuth 2.1 + Server | 验证调用方身份       |
| **权限控制** | Server             | 控制不同用户的工具访问权限 |
| **数据隐私** | Server + Host      | 不泄露敏感数据给AI模型  |
| **工具安全** | Host               | 高风险工具调用需用户确认  |

## 7.2 OAuth 2.1认证

MCP规范基于 **OAuth 2.1**（draft-ietf-oauth-v2-1-13）定义远程Server的认证机制。这不是MCP发明的新认证方案，而是完全基于现有OAuth标准和相关RFC规范。

### 涉及的RFC标准

| RFC                      | 名称                            | 在MCP中的作用                 |
| ------------------------ | ----------------------------- | ------------------------ |
| draft-ietf-oauth-v2-1-13 | OAuth 2.1                     | 核心授权框架                   |
| RFC 7636 (PKCE)          | Proof Key for Code Exchange   | 防止授权码拦截攻击（MCP强制要求S256方法） |
| RFC 8414                 | Authorization Server Metadata | Client自动发现授权服务器的端点和能力    |
| RFC 7591                 | Dynamic Client Registration   | Client首次连接时自动注册          |
| RFC 9728                 | Protected Resource Metadata   | Server声明自己的认证要求和关联的授权服务器 |
| RFC 8707                 | Resource Indicators           | Client指定请求token的目标资源     |

### 完整认证流程

```
Step 1: Client向MCP Server端点发送请求
        → Server返回401 Unauthorized

Step 2: Client获取Protected Resource Metadata (RFC 9728)
        GET https://mcp-server.example.com/.well-known/oauth-protected-resource
        → 获得authorization_servers列表

Step 3: Client获取Authorization Server Metadata (RFC 8414)
        GET https://auth.example.com/.well-known/oauth-authorization-server
        → 获得authorization_endpoint, token_endpoint等

Step 4: Dynamic Client Registration (RFC 7591, 如需)
        POST https://auth.example.com/register
        → 获得client_id（无client_secret，因为是公共客户端）

Step 5: Authorization Code + PKCE (S256)
        a. Client生成code_verifier和code_challenge
        b. 引导用户访问authorization_endpoint
        c. 用户授权后获得authorization_code
        d. Client用code + code_verifier换取access_token

Step 6: 后续请求携带Bearer Token
        POST https://mcp-server.example.com/mcp
        Authorization: Bearer eyJhbG...
        Mcp-Session-Id: session-abc123
```

### PKCE (Proof Key for Code Exchange)

MCP**强制要求**PKCE，且必须使用 `S256` 方法（不允许 `plain`）。PKCE防止授权码被中间人拦截后滥用：

```
// 1. Client生成随机code_verifier
code_verifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

// 2. 计算code_challenge = BASE64URL(SHA256(code_verifier))
code_challenge = "E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM"

// 3. 授权请求携带code_challenge
GET /authorize?
  response_type=code&
  client_id=my-client&
  code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&
  code_challenge_method=S256&
  redirect_uri=http://localhost:8080/callback

// 4. 换取token时携带code_verifier
POST /token
  grant_type=authorization_code&
  code=AUTH_CODE&
  code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
```

### Token类型

MCP使用 **Bearer Token**。access\_token在HTTP请求头中传递：

```
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
```

## 7.3 Server端认证实现

```typescript theme={null}
import express from "express";

const app = express();

// OAuth token验证中间件
async function authenticate(req, res, next) {
  const token = req.headers.authorization?.replace("Bearer ", "");
  if (!token) {
    // 返回401，引导Client进行OAuth认证
    return res.status(401).json({
      error: "unauthorized"
    });
  }

  // 验证token（调用授权服务器的introspection端点或本地JWT验证）
  const user = await verifyToken(token);
  if (!user) return res.status(403).json({ error: "invalid_token" });

  req.user = user;
  next();
}

// Protected Resource Metadata端点 (RFC 9728)
app.get("/.well-known/oauth-protected-resource", (req, res) => {
  res.json({
    resource: "https://mcp-server.example.com",
    authorization_servers: ["https://auth.example.com"],
    bearer_methods_supported: ["header"]
  });
});

// MCP端点（需认证）
app.post("/mcp", authenticate, async (req, res) => {
  const result = await handleMcpRequest(req.body, req.user);
  res.json(result);
});
```

## 7.4 权限控制

不同工具需要不同权限级别：

```typescript theme={null}
// 工具执行时检查权限
server.tool("create_return", "发起退货", schema, async (args, context) => {
  // 检查用户是否有权操作这个订单
  const order = await db.orders.findById(args.orderId);
  if (order.userId !== context.user.id) {
    return {
      content: [{ type: "text", text: "无权操作此订单" }],
      isError: true
    };
  }
  // 执行退货逻辑
  const returnRequest = await db.returns.create({
    orderId: args.orderId,
    reason: args.reason,
    userId: context.user.id
  });
  return {
    content: [{
      type: "text",
      text: `退货申请已创建: ${returnRequest.id}`
    }]
  };
});
```

### 工具级权限矩阵

建议为每个工具定义明确的权限要求：

| 权限级别 | 说明                 | 示例工具                                    |
| ---- | ------------------ | --------------------------------------- |
| 公开   | 无需认证               | `search_products`, `get_categories`     |
| 登录   | 需要有效的access\_token | `get_order`, `list_orders`              |
| 所有者  | 只能操作自己的数据          | `create_return`, `update_profile`       |
| 管理员  | 需要管理员权限            | `update_inventory`, `manage_promotions` |

## 7.5 数据隐私

**原则**: Server返回的数据会被AI模型处理。不要在工具返回中包含不应该被AI"看到"的敏感信息。

| 可以返回      | 不应返回      |
| --------- | --------- |
| 商品名、价格、库存 | 用户密码、支付凭证 |
| 订单状态、物流信息 | 完整信用卡号    |
| 公开的公司信息   | 内部成本价、利润率 |
| 脱敏后的用户信息  | 完整身份证号    |

### Resource的Annotations辅助隐私控制

通过Annotations的 `audience` 字段控制资源的目标受众：

```json theme={null}
{
  "uri": "commerce://analytics/daily",
  "annotations": {
    "audience": ["assistant"],
    "priority": 0.3
  }
}
```

`audience: ["assistant"]` 表示该资源仅供AI模型处理，不应直接展示给用户。Host可以据此决定是否在UI中隐藏该资源。

## 7.6 传输安全

### 远程Server（Streamable HTTP）

* **强制HTTPS**: 生产环境必须使用TLS加密
* **证书验证**: Client应验证Server的TLS证书
* **CORS**: 如果Client是浏览器应用，Server需配置适当的CORS策略

### 本地Server（stdio）

stdio本地Server天然安全（不暴露网络），但仍需注意：

* 不要硬编码数据库密码在代码中，用环境变量
* 限制文件系统访问范围（配合Roots机制）
* 日志不要记录敏感数据
* Server进程以最小权限运行

## 7.7 安全检查清单

开发MCP Server时，对照以下清单确保安全：

* 远程Server是否使用HTTPS
* 是否实现了OAuth 2.1认证（含PKCE S256）
* 敏感工具是否检查了用户权限
* 返回数据是否经过脱敏处理
* 环境变量是否用于存储密钥
* 日志中是否排除了敏感信息
* 是否对输入参数进行了验证和清理
* 是否实现了请求频率限制

***

**下一章**: [测试与调试](/zh/book-5/ch8-testing) — MCP Inspector使用指南
