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状态码。
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混淆。
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隔离故障排查”课程的核心实践。