314 lines
6.8 KiB
Markdown
314 lines
6.8 KiB
Markdown
# TMS Auth Refactor Design
|
||
|
||
**Date:** 2026-03-30
|
||
|
||
## Goal
|
||
|
||
在 `tms-framework` 中重构认证模块,完整承接旧管理端的认证标准流程,但只保留一套新规范接口与一套实现代码。重构范围只调整接口命名、DTO 字段命名、控制器职责和数据模型表达方式,不改变旧系统的业务判断顺序和安全规则。
|
||
|
||
## Confirmed Scope
|
||
|
||
本设计覆盖:
|
||
|
||
- `SUPER_ADMIN / KEY_ADMIN / AUDIT_ADMIN / OPS_ADMIN` 四个正式角色
|
||
- 口令登录与 UKey 登录两条标准流程
|
||
- 角色启用、重置密码、UKey 发行签名、UKey 绑定
|
||
- 当前会话、退出登录、修改密码
|
||
- `modules/auth/controller` 最终只保留新规范接口
|
||
|
||
本设计不覆盖:
|
||
|
||
- 前端页面重构
|
||
- PCIe / UKey 底层驱动实现重写
|
||
- 主密钥业务规则调整
|
||
- `/openapi/**` 外部接口鉴权模型
|
||
|
||
## Legacy Semantics To Preserve
|
||
|
||
### 1. Four main roles
|
||
|
||
旧系统主角色与新系统角色一一对应:
|
||
|
||
- `superadmin -> SUPER_ADMIN`
|
||
- `keyadmin -> KEY_ADMIN`
|
||
- `auditadmin -> AUDIT_ADMIN`
|
||
- `configadmin -> OPS_ADMIN`
|
||
|
||
### 2. UKey login is the standard full-auth flow
|
||
|
||
旧系统对上述四个主角色的标准登录方式是 `UKey + 角色口令`。
|
||
|
||
固定 UKey 数量要求:
|
||
|
||
- `SUPER_ADMIN` 需要 3 把 UKey
|
||
- `KEY_ADMIN` 需要 2 把 UKey
|
||
- `AUDIT_ADMIN` 需要 1 把 UKey
|
||
- `OPS_ADMIN` 需要 1 把 UKey
|
||
|
||
旧系统 UKey 登录必须保留的校验顺序:
|
||
|
||
1. 角色与 `rid` 组合匹配
|
||
2. UKey 发行签名校验
|
||
3. `uid/rid` 与角色认证信息匹配
|
||
4. 主密钥状态校验
|
||
5. 后端随机数校验
|
||
6. 登录签名校验
|
||
7. 白名单校验
|
||
8. 角色口令校验
|
||
|
||
### 3. Password login is a limited-auth flow
|
||
|
||
旧系统存在口令登录链路。新系统不再保留 `KEY_ADMIN_A / KEY_ADMIN_B / auditadmin_user / configadmin_user` 这样的历史角色代码,而是将其收敛为四个主角色在 `LIMITED` 认证等级下的登录结果。
|
||
|
||
也就是说:
|
||
|
||
- 口令登录成功 -> 同一主角色的 `LIMITED` 会话
|
||
- UKey 登录成功 -> 同一主角色的 `FULL` 会话
|
||
|
||
### 4. UKey binding is still a two-step process
|
||
|
||
旧系统“绑定角色 UKey”本质上是:
|
||
|
||
1. 生成发行签名
|
||
2. 绑定落库 / 写卡完成后的登记
|
||
|
||
这个两步流程必须保留,只是统一为新接口命名。
|
||
|
||
## Domain Model
|
||
|
||
### Roles
|
||
|
||
只保留四个正式角色枚举:
|
||
|
||
- `SUPER_ADMIN`
|
||
- `KEY_ADMIN`
|
||
- `AUDIT_ADMIN`
|
||
- `OPS_ADMIN`
|
||
|
||
### AuthMethod
|
||
|
||
- `PASSWORD`
|
||
- `UKEY`
|
||
|
||
### AuthLevel
|
||
|
||
- `LIMITED`
|
||
- `FULL`
|
||
|
||
关系约束:
|
||
|
||
- `PASSWORD -> LIMITED`
|
||
- `UKEY -> FULL`
|
||
|
||
`roleCode` 表达“是谁”,`authLevel` 表达“当前认证强度”。接口权限只基于 `roleCode + authLevel` 判断,不再通过附加影子角色表达。
|
||
|
||
## API Contract
|
||
|
||
只保留新规范路径,不再保留兼容旧路径控制器。
|
||
|
||
### Authentication APIs
|
||
|
||
- `POST /api/v1/auth/password-login`
|
||
- `POST /api/v1/auth/ukey-login/randoms`
|
||
- `POST /api/v1/auth/ukey-login`
|
||
- `POST /api/v1/auth/captcha`
|
||
- `GET /api/v1/auth/me`
|
||
- `POST /api/v1/auth/logout`
|
||
- `POST /api/v1/auth/change-password`
|
||
|
||
#### password-login
|
||
|
||
入参:
|
||
|
||
- `roleCode`
|
||
- `password`
|
||
- `captchaCode`
|
||
- `captchaId`
|
||
|
||
行为:
|
||
|
||
- 按旧口令登录顺序校验主密钥状态、验证码、密码和失败次数
|
||
- 成功后签发该角色的 `LIMITED` 会话
|
||
|
||
#### ukey-login/randoms
|
||
|
||
入参:
|
||
|
||
- `roleCode`
|
||
|
||
行为:
|
||
|
||
- 按角色要求下发固定数量随机数
|
||
|
||
#### ukey-login
|
||
|
||
入参:
|
||
|
||
- `roleCode`
|
||
- `password`
|
||
- `ukeyProofs[]`
|
||
|
||
单个 `ukeyProofs[]` 项包含:
|
||
|
||
- `pubKey`
|
||
- `uid`
|
||
- `rid`
|
||
- `serverRandom`
|
||
- `issueSignature`
|
||
- `loginPayload`
|
||
- `loginSignature`
|
||
|
||
行为:
|
||
|
||
- 完整保留旧项目 UKey 登录校验顺序
|
||
- 成功后签发 `FULL` 会话
|
||
|
||
### Role Administration APIs
|
||
|
||
- `POST /api/v1/auth/roles/{roleCode}/enable`
|
||
- `POST /api/v1/auth/roles/{roleCode}/reset-password`
|
||
- `POST /api/v1/auth/roles/{roleCode}/ukeys/issue-sign`
|
||
- `POST /api/v1/auth/roles/{roleCode}/ukeys/bind`
|
||
|
||
这些接口统一要求:
|
||
|
||
- `KEY_ADMIN`
|
||
- `FULL`
|
||
|
||
## Data Model
|
||
|
||
### 1. tms_auth_role_account
|
||
|
||
统一角色账户表,只保留四个主角色:
|
||
|
||
- `role_code`
|
||
- `display_name`
|
||
- `required_ukey_count`
|
||
- `password_hash`
|
||
- `password_salt`
|
||
- `status`
|
||
- `need_change_password`
|
||
- `failed_count`
|
||
- `locked_until`
|
||
- `last_login_at`
|
||
- `last_active_at`
|
||
|
||
### 2. tms_auth_role_ukey_binding
|
||
|
||
统一 UKey 绑定表:
|
||
|
||
- `role_code`
|
||
- `slot_no`
|
||
- `uid`
|
||
- `rid`
|
||
- `ukey_serial`
|
||
- `ukey_pubkey`
|
||
- `issuer_sign`
|
||
- `status`
|
||
- `bound_at`
|
||
- `unbound_at`
|
||
|
||
`slot_no`、`uid`、`rid` 是承接旧系统流程的必要字段,不能省略。
|
||
|
||
### 3. tms_auth_session
|
||
|
||
统一会话表:
|
||
|
||
- `session_token`
|
||
- `role_code`
|
||
- `auth_method`
|
||
- `auth_level`
|
||
- `issued_at`
|
||
- `last_active_at`
|
||
- `expires_at`
|
||
- `logout_at`
|
||
|
||
### 4. Captcha storage
|
||
|
||
验证码优先继续使用内存缓存,不在本次设计中新增持久化表。
|
||
|
||
## Controller Structure
|
||
|
||
`modules/auth/controller` 最终只保留一套规范控制器:
|
||
|
||
- `AuthController`
|
||
- 认证、当前会话、修改密码
|
||
- `AuthAdminController`
|
||
- 角色管理、UKey 发行签名、UKey 绑定
|
||
|
||
删除:
|
||
|
||
- `CompatAuthController`
|
||
|
||
## Service Structure
|
||
|
||
建议保留三类核心服务职责:
|
||
|
||
- `AuthService`
|
||
- `passwordLogin`
|
||
- `ukeyLogin`
|
||
- `issueUkeyLoginRandoms`
|
||
- `issueCaptcha`
|
||
- `me`
|
||
- `logout`
|
||
- `changePassword`
|
||
- `AuthAdminService`
|
||
- `enableRole`
|
||
- `resetPassword`
|
||
- `issueUkeyBindingSign`
|
||
- `bindIssuedUkey`
|
||
- `AuthPolicyService`
|
||
- 角色 UKey 数要求
|
||
- `LIMITED/FULL` 接口权限策略
|
||
- 主角色与旧登录规则映射
|
||
|
||
## Security and Permission Rules
|
||
|
||
新系统的权限表达统一为:
|
||
|
||
- `roleCode`
|
||
- `authLevel`
|
||
|
||
示例:
|
||
|
||
- `KEY_ADMIN + FULL` 可启用角色、重置角色口令、绑定 UKey
|
||
- `KEY_ADMIN + LIMITED` 只能访问受限密钥管理接口
|
||
- `AUDIT_ADMIN + LIMITED` 只能访问受限审计接口
|
||
- `AUDIT_ADMIN + FULL` 可访问完整审计接口
|
||
- `OPS_ADMIN + LIMITED` 只能访问受限运维接口
|
||
- `OPS_ADMIN + FULL` 可访问完整运维接口
|
||
- `SUPER_ADMIN + FULL` 才能访问最高敏感操作
|
||
|
||
## Migration Strategy
|
||
|
||
本次重构不是保留旧接口再适配,而是:
|
||
|
||
1. 只保留新接口
|
||
2. 在服务层完整承接旧业务流程
|
||
3. 删除 `CompatAuthController` 及其兼容 DTO/测试
|
||
4. 通过数据库迁移补齐 `uid/rid/auth_method/auth_level` 等字段
|
||
|
||
## Testing Strategy
|
||
|
||
至少覆盖:
|
||
|
||
- 口令登录成功签发 `LIMITED`
|
||
- UKey 登录成功签发 `FULL`
|
||
- UKey 数量不足失败
|
||
- `rid` 组合不匹配失败
|
||
- 发行签名校验失败
|
||
- 登录签名校验失败
|
||
- 主密钥未就绪失败
|
||
- 角色启用、重置密码、绑定 UKey 权限限制
|
||
- 删除兼容控制器后 OpenAPI 与控制器测试同步更新
|
||
|
||
## Final Decision
|
||
|
||
本次 auth 重构最终基线为:
|
||
|
||
- 只保留新规范接口
|
||
- 只保留四个正式角色
|
||
- 保留两条标准登录流程
|
||
- 使用 `authLevel` 区分认证强度和接口权限
|
||
- `auth/controller` 仅保留一套规范控制器实现
|