feat(auth): add Redis authorization caching

This commit is contained in:
2026-08-01 12:20:31 +08:00
parent 84c2b0b21d
commit 46abf4d62f
36 changed files with 21757 additions and 35 deletions

View File

@@ -0,0 +1,39 @@
# Redis 认证授权缓存
## 请求链路
受保护请求先在本地完成 JWT 验签,再通过一次 Redis MGET 校验 Session、用户、租户、成员资格和持久化授权版本。权限快照使用 60 秒进程内缓存和 5 分钟 Redis 缓存本地快照键包含授权版本因此撤权后的下一请求不会继续使用旧权限。PostgreSQL 始终是事实源Redis 读取失败时绕过本地快照并回退数据库。
缓存不保存 JWT、Refresh Token、手机号或邮箱。Redis key 使用环境隔离前缀,并区分 platform/tenant realm、tenant、user 和 session。
## 配置与故障语义
```json
{
"Security": {
"AuthorizationCache": {
"Mode": "Disabled",
"LocalSnapshotSeconds": 60,
"DistributedStateSeconds": 60,
"DistributedSnapshotSeconds": 300,
"JitterPercent": 20
}
}
}
```
- `Disabled`:保持 PostgreSQL 权威读取,仅维护持久化授权版本。
- `Shadow`PostgreSQL 决策仍为准,同时读取、回填和比较 Redis 结果。
- `Active`Redis 为主要读取路径,缓存缺失或不可用时回退 PostgreSQL。
- Redis 与 PostgreSQL 同时不可用时返回 `503`,错误码为 `auth_security_unavailable`
生产环境的 API 和 Worker 都必须配置 `ConnectionStrings:Redis``REDIS_URL`。Worker 重试 `authorization_cache_invalidations` 中未完成的失效事件Redis 版本写入是单调的,旧事件不会覆盖新版本。
## 发布与回滚
1. 先部署迁移,保持 `Disabled`
2. 切换 `Shadow`,观察 `Tiku.Security.AuthorizationCache` 指标中的 mismatch、fallback 和 Redis 延迟。
3. 确认无非并发不一致后,对单实例启用 `Active`,再逐步扩容。
4. 回滚时只把模式切回 `Disabled`,不回退数据库迁移。
RBAC 表和权限目录由 PostgreSQL 触发器在业务事务内推进授权版本并写入失效事件。任何新增的用户、成员、租户、Session 或角色权限写路径,也必须调用 `IAuthorizationStateInvalidator` 完成同步 Redis 失效。