4. API安全设计:认证机制(OAuth2/JWT)、授权模型、API密钥管理

API安全是API治理的基石。在Mock隔离故障排查场景中,安全配置错误(如Token过期、Scope缺失、密钥轮换未同步)是导致Mock与真实环境行为不一致的常见根因。本章聚焦认证、授权与密钥管理三大核心领域,建立可审计、可复现的安全设计规范。

4.1 认证机制:OAuth2与JWT

认证(Authentication)解决“你是谁”的问题。现代API主要采用OAuth2授权框架配合JWT(JSON Web Token)作为凭证载体。

4.1.1 OAuth2授权流程

OAuth2定义了四种授权模式,适用于不同场景。在API治理中,最常用的是授权码模式(Authorization Code)和客户端凭证模式(Client Credentials)。

授权模式 适用场景 安全等级 典型用户
授权码模式 第三方应用访问用户资源 高(支持PKCE) Web/移动App
客户端凭证模式 服务间通信(M2M) 中 后端服务、Mock服务
隐式模式(已弃用) 纯前端应用(不推荐) 低 SPA(已迁移至PKCE)
密码模式(已弃用) 受信任第一方应用 低 遗留系统
治理要点:在Mock隔离测试中,建议统一使用客户端凭证模式颁发测试专用Token,避免用户交互流程干扰自动化测试。Token有效期应缩短至5-15分钟,降低泄露风险。

4.1.2 JWT结构与验证

JWT由三部分组成:Header(头部)、Payload(载荷)、Signature(签名)。API网关或Mock服务必须验证JWT的签名、过期时间(exp)和颁发者(iss)。

// JWT示例(解码后)
{
  "header": {
    "alg": "RS256",
    "typ": "JWT",
    "kid": "key-id-2024-01"
  },
  "payload": {
    "iss": "https://auth.example.com",
    "sub": "service-mock-01",
    "aud": ["api-gateway", "mock-server"],
    "exp": 1700000000,
    "iat": 1699996400,
    "scope": "read:orders write:orders"
  },
  "signature": "Base64Url(RSASHA256(header.payload, privateKey))"
}
Mock隔离故障案例:某团队在Mock环境中使用了硬编码的JWT,未验证exp字段。当真实环境Token过期后,Mock仍返回200,导致故障排查延误3小时。规范要求:Mock必须模拟Token过期行为,返回401状态码。
OAuth2 授权码模式流程(含Mock隔离点) 用户代理 客户端应用 授权服务器 资源服务器 Mock服务 (隔离点) ① 请求授权 ② 重定向至授权服务器 ③ 授权码 ④ 颁发Token ⑤ 携带Token请求 ⑥ 验证Token Mock隔离故障排查要点 • Mock服务应模拟授权服务器的Token颁发行为,但使用独立密钥对 • 步骤⑤中,Mock必须验证Token的签名、exp、aud和scope • 建议在Mock中注入Token过期、Scope不足等异常场景,验证客户端容错 • 真实环境与Mock环境的JWKS端点必须隔离,避免密钥泄露

4.2 授权模型:RBAC与ABAC

授权(Authorization)解决“你能做什么”的问题。API治理中,推荐采用基于角色的访问控制(RBAC)作为基础模型,复杂场景可叠加基于属性的访问控制(ABAC)。

4.2.1 RBAC模型

RBAC通过角色(Role)将用户与权限解耦。API网关根据JWT中的角色信息,决定是否放行请求。

组件 说明 示例
用户(User) API调用者 service-mock-01
角色(Role) 权限集合 read_only, admin, mock_tester
权限(Permission) 对资源的操作 read:orders, write:orders
资源(Resource) API端点 /api/v1/orders

4.2.2 Scope与权限粒度

OAuth2的Scope字段是授权的最小单元。API网关应基于Scope进行细粒度控制,避免“全有或全无”的粗放授权。

// 基于Scope的授权策略示例(伪代码)
function authorizeRequest(token, requestPath, method) {
  const scopes = token.payload.scope.split(' ');
  
  // 定义资源-方法-Scope映射
  const scopeMap = {
    'GET /api/v1/orders': 'read:orders',
    'POST /api/v1/orders': 'write:orders',
    'DELETE /api/v1/orders': 'admin:orders'
  };
  
  const requiredScope = scopeMap[`${method} ${requestPath}`];
  if (!requiredScope) return false; // 未定义路径,拒绝
  
  return scopes.includes(requiredScope);
}
治理规范:所有API端点必须声明所需的Scope,并在API描述文档(OpenAPI)中标注。Mock环境应使用独立的Scope集合(如mock:read:orders),避免与生产Scope混淆。
RBAC授权模型与API网关决策流程 用户A 用户B Mock服务 read_only admin mock_tester read:orders write:orders admin:orders API网关 决策引擎 验证JWT 匹配Scope 返回决策

4.3 API密钥管理

API密钥(API Key)是服务间认证的轻量方案,但管理不当会带来严重安全风险。治理规范要求建立密钥全生命周期管理机制。

4.3.1 密钥生命周期

阶段 操作 治理要求
生成 创建密钥对 使用加密安全的随机数生成器,长度≥256位
分发 安全传输至客户端 通过密钥管理服务(KMS)或加密通道分发
存储 保存密钥 禁止硬编码;使用环境变量或密钥存储库
使用 API调用时携带 通过Header(X-API-Key)传递,禁止URL参数
轮换 定期更换密钥 每90天强制轮换,支持双密钥并行过渡
吊销 废弃密钥 立即生效,记录吊销审计日志

4.3.2 Mock环境密钥隔离策略

在Mock隔离测试中,密钥管理是故障高发区。以下策略可有效降低风险:

  • 独立密钥池:Mock环境使用独立的API Key和JWT签名密钥,与生产环境完全隔离。
  • 密钥前缀标识:Mock密钥添加前缀(如 mock_),便于审计和过滤。
  • 自动过期:Mock密钥有效期不超过24小时,测试结束后自动吊销。
  • 密钥轮换同步:Mock环境与真实环境的密钥轮换节奏解耦,避免轮换不同步导致的认证失败。
// Mock环境密钥配置示例(环境变量)
MOCK_API_KEY=mock_sk_live_abc123def456
MOCK_JWT_PRIVATE_KEY=-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA...\n-----END RSA PRIVATE KEY-----
MOCK_JWT_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...\n-----END PUBLIC KEY-----
MOCK_KEY_EXPIRY_HOURS=24
常见故障:某团队在Mock环境中使用了生产环境的JWT公钥进行签名验证,导致Mock服务无法验证由Mock私钥签发的Token。规范要求:Mock环境必须使用独立的JWKS端点,且客户端在Mock环境中应配置Mock的JWKS URL。

4.4 安全设计检查清单

以下清单用于API设计评审和Mock隔离测试前的安全合规检查:

检查项 通过标准 Mock验证方法
JWT签名验证 所有API端点验证JWT签名 使用篡改Token请求,预期返回401
Token过期处理 过期Token返回401,非500 使用过期Token请求,验证响应码
Scope最小化 每个端点只声明所需Scope 使用缺少Scope的Token请求,预期返回403
密钥隔离 Mock与生产密钥完全独立 验证Mock密钥前缀和存储路径
密钥轮换 支持双密钥并行过渡 模拟轮换场景,新旧密钥均可用
审计日志 所有认证失败记录日志 触发认证失败,检查日志输出
自动化建议:将安全检查清单集成到API治理平台的自动化测试套件中。每次Mock环境部署后,自动执行安全合规扫描,生成证据报告。这是“基于证据报告的Mock隔离故障排查”课程的核心实践。