Files
2026-08-13 19:01:16 +08:00

77 lines
3.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 国内与海外 JWT/JWKS 冻结契约
## 双轨边界
### 国内现有链路
- 登录、刷新、退出和代登录接口保持原契约,不修改 `TokenResponse`。
- 签名算法保持 `HS256`,继续使用 `JWT_SECRET`。
- Access Token 默认有效期保持 24 分钟,Refresh Token 默认有效期保持 7 天。
- 业务服务继续使用国内 HMAC 验签与 Redis 会话校验,账号停用、退出和 Token 版本失效规则不变。
- 国内 Token 保持现有 snake_case 声明,不增加海外 `aud`,也不要求配置 RSA/JWK。
### 海外尾程链路
- 海外能力默认关闭:`OVERSEAS_JWT_ENABLED=false`。
- 已通过国内 HS256 与 Redis 校验的登录用户调用 `POST /api/auth/overseas/token`,兑换独立的海外短时 Token。
- 海外 Token 使用 `RS256`,默认有效期 15 分钟,不签发 Refresh Token。
- 尾程必须配置 `baiyue.security.jwt-mode=jwks` 和 `baiyue.security.session-mode=claims`,只做 JWKS 验签和本地安全投影校验,不创建或访问国内 Redis 会话校验器。
- 海外功能未启用时,兑换接口返回“海外认证未启用”;JWKS Controller、海外签发服务和 `overseasJwtEncoder` 均不创建,Auth 仍可正常启动并签发国内 HS256 Token。
## 海外签发契约
- `issuer`:`auth-service`
- `audience`:`lastleg-api`
- 算法白名单:仅 `RS256`
- Access Token 默认有效期:15 分钟
- 兑换接口:`POST /api/auth/overseas/token`
- JWKS 路径:`/api/auth/.well-known/jwks.json`
- Auth 直连地址:`http://{auth-host}:9100/api/auth/.well-known/jwks.json`
- JWKS HTTP 缓存:5 分钟,响应 `Cache-Control: public, max-age=300`
海外 Token 的 JSON 声明名称和类型固定如下:
| 声明 | JSON 类型 | 说明 |
|---|---|---|
| `sub` | string | 用户 ID 的字符串形式 |
| `jti` | string | Token 唯一标识 |
| `iat` | number | 签发时间 |
| `exp` | number | 过期时间 |
| `aud` | string array | 固定包含 `lastleg-api` |
| `userId` | number | 认证用户 ID |
| `tenantId` | number | 当前客户 ID;平台账号为平台作用域值 |
| `appCode` | string | `PLATFORM` 或 `MERCHANT` |
| `roles` | string array | 当前角色编码快照 |
| `authorities` | string array | 当前权限编码快照 |
| `permissionVersion` | number | IAM 单调权限版本 |
海外 Token 从 V1 起只使用上述 camelCase 自定义声明,不读取国内 snake_case 声明。
## 海外配置
```yaml
baiyue:
security:
overseas-jwt:
enabled: ${OVERSEAS_JWT_ENABLED:false}
issuer: ${OVERSEAS_JWT_ISSUER:auth-service}
audience: ${OVERSEAS_JWT_AUDIENCE:lastleg-api}
rsa-jwk-set: ${OVERSEAS_JWT_RSA_JWK_SET:}
current-kid: ${OVERSEAS_JWT_CURRENT_KID:}
access-token-ttl: ${OVERSEAS_ACCESS_TOKEN_TTL:15m}
```
只有显式启用海外能力时才校验 `OVERSEAS_JWT_RSA_JWK_SET` 和 `OVERSEAS_JWT_CURRENT_KID`。启用后配置不合法必须启动失败,避免错误密钥签发。
## 密钥轮换
- JWK Set 只允许 RSA 密钥。
- `OVERSEAS_JWT_CURRENT_KID` 必须指向唯一的当前签名私钥,JWT Header 写入该 `kid`。
- 非当前密钥只能保留公钥;JWKS 只发布公钥,不得输出私钥参数。
- 轮换时同时发布当前公钥和上一公钥,上一公钥至少保留 20 分钟,即 15 分钟最大 Token 生命周期加 5 分钟 JWKS 缓存。
- 重叠期结束后移除上一公钥,禁止复用历史 `kid`。
## IAM 安全事件
安全事件的 `eventType`、版本、状态枚举和 payload 以 `iam/SECURITY-EVENT-AUDIT.md` 为唯一契约。尾程维护用户状态、客户状态和权限版本的本地投影,请求期间不反向同步访问国内 IAM。