377 lines
7.9 KiB
Markdown
377 lines
7.9 KiB
Markdown
# 管理员操作审计功能设计
|
||
|
||
## 1. 目标
|
||
|
||
统一使用 `tms_operation_audit_log` 记录所有敏感管理员操作,覆盖:
|
||
|
||
- 登录、登出
|
||
- 增删改
|
||
- 执行类操作:初始化、重置、升级、回滚、重启、密钥操作
|
||
- 非法操作:拒绝访问、权限不足、重放、签名失败等
|
||
|
||
设计原则:
|
||
|
||
- 只保留一张日志表
|
||
- 敏感操作日志写入失败时,业务直接失败
|
||
- 日志在落库前完成 `SM3` 摘要与 `SM2` 签名
|
||
- 人工审计字段不参与首签
|
||
|
||
## 2. 表结构
|
||
|
||
表名:`tms_operation_audit_log`
|
||
|
||
```sql
|
||
CREATE TABLE IF NOT EXISTS tms_operation_audit_log (
|
||
id BIGINT PRIMARY KEY,
|
||
log_id VARCHAR(64) NOT NULL COMMENT '日志唯一标识',
|
||
operator_role_code VARCHAR(64) NOT NULL COMMENT '操作角色编码',
|
||
operator_auth_level VARCHAR(32) NULL COMMENT '操作时认证等级',
|
||
module_code VARCHAR(32) NOT NULL COMMENT '业务模块',
|
||
action_type VARCHAR(32) NOT NULL COMMENT '操作动作',
|
||
remote_ip VARCHAR(64) NULL COMMENT '来源IP',
|
||
operation_result VARCHAR(16) NOT NULL COMMENT '操作结果: SUCCESS/FAILED/DENIED',
|
||
summary VARCHAR(512) NOT NULL COMMENT '操作摘要',
|
||
error_message VARCHAR(1024) NULL COMMENT '失败原因',
|
||
audit_status VARCHAR(16) NOT NULL COMMENT '审计状态: PENDING/REVIEWED',
|
||
audit_result VARCHAR(16) NULL COMMENT '审计结果: PASS/REJECT/NEED_VERIFY',
|
||
audit_comment VARCHAR(1024) NULL COMMENT '审计意见',
|
||
audited_by VARCHAR(64) NULL COMMENT '审计人',
|
||
audited_at DATETIME(3) NULL COMMENT '审计时间',
|
||
payload_hash VARCHAR(128) NOT NULL COMMENT 'SM3摘要',
|
||
sign_value TEXT NOT NULL COMMENT 'SM2签名值',
|
||
occurred_at DATETIME(3) NOT NULL COMMENT '操作发生时间',
|
||
create_time DATETIME(3) NOT NULL COMMENT '落库时间',
|
||
UNIQUE KEY uk_tms_operation_audit_log_log_id (log_id),
|
||
KEY idx_tms_operation_audit_log_role_code (operator_role_code),
|
||
KEY idx_tms_operation_audit_log_module_code (module_code),
|
||
KEY idx_tms_operation_audit_log_action_type (action_type),
|
||
KEY idx_tms_operation_audit_log_result (operation_result),
|
||
KEY idx_tms_operation_audit_log_audit_status (audit_status),
|
||
KEY idx_tms_operation_audit_log_occurred_at (occurred_at)
|
||
);
|
||
```
|
||
|
||
## 3. 枚举设计
|
||
|
||
### 3.1 `module_code`
|
||
|
||
- `AUTH`
|
||
- `INIT`
|
||
- `UPGRADE`
|
||
- `DEVICE`
|
||
- `NETWORK`
|
||
- `KEY`
|
||
- `SYSTEM`
|
||
- `SECURITY`
|
||
|
||
### 3.2 `action_type`
|
||
|
||
- `LOGIN`
|
||
- `LOGOUT`
|
||
- `CREATE`
|
||
- `UPDATE`
|
||
- `DELETE`
|
||
- `EXECUTE`
|
||
- `RESET`
|
||
- `ENABLE`
|
||
- `DISABLE`
|
||
- `BIND`
|
||
- `IMPORT`
|
||
- `EXPORT`
|
||
- `BACKUP`
|
||
- `RECOVER`
|
||
- `RESTART`
|
||
- `ACCESS`
|
||
|
||
### 3.3 `operation_result`
|
||
|
||
- `SUCCESS`
|
||
- `FAILED`
|
||
- `DENIED`
|
||
|
||
### 3.4 `audit_status`
|
||
|
||
- `PENDING`
|
||
- `REVIEWED`
|
||
|
||
### 3.5 `audit_result`
|
||
|
||
- `PASS`
|
||
- `REJECT`
|
||
- `NEED_VERIFY`
|
||
|
||
## 4. 摘要与签名
|
||
|
||
### 4.1 首签字段
|
||
|
||
入库前参与 `payload_hash` 和 `sign_value` 计算的字段:
|
||
|
||
- `log_id`
|
||
- `operator_role_code`
|
||
- `operator_auth_level`
|
||
- `module_code`
|
||
- `action_type`
|
||
- `remote_ip`
|
||
- `operation_result`
|
||
- `summary`
|
||
- `occurred_at`
|
||
|
||
### 4.2 不参与首签的字段
|
||
|
||
以下字段属于后续审计动作或补充信息,不参与首签:
|
||
|
||
- `audit_status`
|
||
- `audit_result`
|
||
- `audit_comment`
|
||
- `audited_by`
|
||
- `audited_at`
|
||
- `error_message`
|
||
|
||
### 4.3 规范化串
|
||
|
||
建议按固定字段顺序拼接:
|
||
|
||
```text
|
||
log_id=...
|
||
operator_role_code=...
|
||
operator_auth_level=...
|
||
module_code=...
|
||
action_type=...
|
||
remote_ip=...
|
||
operation_result=...
|
||
summary=...
|
||
occurred_at=...
|
||
```
|
||
|
||
规范要求:
|
||
|
||
- 字段顺序固定
|
||
- `null` 统一为空串
|
||
- 首尾空格统一裁剪
|
||
- 时间统一使用 UTC 与固定格式
|
||
|
||
### 4.4 签名流程
|
||
|
||
1. 构造 `canonical_payload`
|
||
2. 计算 `payload_hash = SM3(canonical_payload)`
|
||
3. 计算 `sign_value = SM2(privateKey, canonical_payload)`
|
||
4. 一次性写入数据库
|
||
|
||
## 5. Java 设计草案
|
||
|
||
核心对象:
|
||
|
||
- `OperationAuditLogEntity`
|
||
- `OperationAuditLogRepository`
|
||
- `OperationAuditService`
|
||
- `OperationAuditCommand`
|
||
- `OperationAuditSigner`
|
||
|
||
服务接口建议:
|
||
|
||
```java
|
||
public interface OperationAuditService {
|
||
|
||
void record(OperationAuditCommand command);
|
||
|
||
void review(String logId, AuditResult auditResult, String auditComment, String auditedBy);
|
||
}
|
||
```
|
||
|
||
`OperationAuditCommand` 建议字段:
|
||
|
||
- `operatorRoleCode`
|
||
- `operatorAuthLevel`
|
||
- `moduleCode`
|
||
- `actionType`
|
||
- `remoteIp`
|
||
- `operationResult`
|
||
- `summary`
|
||
- `errorMessage`
|
||
|
||
## 6. 日志记录流程
|
||
|
||
统一入口:`OperationAuditService.record(...)`
|
||
|
||
处理流程:
|
||
|
||
1. 业务侧提交 `OperationAuditCommand`
|
||
2. 服务补齐:
|
||
- `log_id`
|
||
- `occurred_at`
|
||
- `audit_status = PENDING`
|
||
3. 生成 `payload_hash` 与 `sign_value`
|
||
4. 插入 `tms_operation_audit_log`
|
||
5. 若插入失败:
|
||
- 对敏感操作直接抛异常,业务失败
|
||
|
||
## 7. 注解与 AOP 接入方案
|
||
|
||
### 7.1 注解定义
|
||
|
||
```java
|
||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||
@Retention(RetentionPolicy.RUNTIME)
|
||
public @interface AuditedOperation {
|
||
|
||
String module();
|
||
|
||
String action();
|
||
|
||
String summary() default "";
|
||
|
||
boolean sensitive() default true;
|
||
}
|
||
```
|
||
|
||
### 7.2 AOP 职责
|
||
|
||
切面负责:
|
||
|
||
- 读取注解元数据
|
||
- 从请求上下文提取:
|
||
- 当前角色
|
||
- 当前认证等级
|
||
- 来源 IP
|
||
- 环绕执行目标方法
|
||
- 成功时记录 `SUCCESS`
|
||
- 捕获业务异常时记录 `FAILED`
|
||
- 捕获权限或安全拒绝时记录 `DENIED`
|
||
- 对 `sensitive = true` 的操作,日志写入失败时重新抛错
|
||
|
||
### 7.3 设计原则
|
||
|
||
- AOP 负责公共字段、结果判定和统一落库
|
||
- 业务方法负责提供准确的 `summary`
|
||
- 不在 AOP 中自动抓取完整请求参数,避免日志带入密码、令牌、密钥材料等敏感数据
|
||
|
||
## 8. 接口清单
|
||
|
||
### 8.1 首批需要接入审计的接口
|
||
|
||
#### 认证与角色管理
|
||
|
||
- `POST /api/v1/auth/password-login`
|
||
- `POST /api/v1/auth/ukey-login`
|
||
- `POST /api/v1/auth/logout`
|
||
- `POST /api/v1/auth/change-password`
|
||
- `POST /api/v1/auth/roles/{roleCode}/enable`
|
||
- `POST /api/v1/auth/roles/{roleCode}/reset-password`
|
||
- `POST /api/v1/auth/roles/{roleCode}/ukeys/bind`
|
||
|
||
#### 初始化与重置
|
||
|
||
- `POST /api/v1/init/tasks`
|
||
- `POST /api/v1/init/tasks/{taskId}/execute`
|
||
- `POST /api/v1/init/reset/tasks`
|
||
- `POST /api/v1/init/reset/tasks/{taskId}/execute`
|
||
|
||
#### 升级管理
|
||
|
||
- `POST /api/v1/upgrades`
|
||
- `POST /api/v1/upgrades/{taskId}/execute`
|
||
- `POST /api/v1/upgrades/{taskId}/rollback`
|
||
|
||
#### 设备与网络
|
||
|
||
- `POST /api/v1/device/restart`
|
||
- 网络配置写接口
|
||
- IP 白名单增删改接口
|
||
|
||
#### 密钥与密码卡
|
||
|
||
- LMK / IK / UKey / 密钥导入导出、备份恢复、销毁相关写接口
|
||
|
||
#### 安全事件
|
||
|
||
- 认证失败
|
||
- 权限不足
|
||
- 重放拦截
|
||
- 签名校验失败
|
||
|
||
### 8.2 日志分页查询接口
|
||
|
||
- `GET /api/v1/audit-logs`
|
||
|
||
查询条件:
|
||
|
||
- `operatorRoleCode`
|
||
- `moduleCode`
|
||
- `actionType`
|
||
- `operationResult`
|
||
- `auditStatus`
|
||
- `auditResult`
|
||
- `remoteIp`
|
||
- `dateFrom`
|
||
- `dateTo`
|
||
- `keyword`
|
||
|
||
默认排序:
|
||
|
||
- `occurred_at DESC`
|
||
|
||
### 8.3 日志详情接口
|
||
|
||
- `GET /api/v1/audit-logs/{logId}`
|
||
|
||
详情建议返回:
|
||
|
||
- 基础日志字段
|
||
- 审计字段
|
||
- `payload_hash`
|
||
- `sign_value`
|
||
|
||
### 8.4 日志审计接口
|
||
|
||
- `POST /api/v1/audit-logs/{logId}/review`
|
||
|
||
请求示例:
|
||
|
||
```json
|
||
{
|
||
"auditResult": "PASS",
|
||
"auditComment": "复核通过"
|
||
}
|
||
```
|
||
|
||
更新规则:
|
||
|
||
- 仅审计管理员可操作
|
||
- 仅允许 `PENDING -> REVIEWED`
|
||
- 更新字段:
|
||
- `audit_status`
|
||
- `audit_result`
|
||
- `audit_comment`
|
||
- `audited_by`
|
||
- `audited_at`
|
||
|
||
## 9. 失败策略
|
||
|
||
敏感操作统一采用失败关闭:
|
||
|
||
- 审计日志写入失败,业务直接失败
|
||
|
||
敏感操作范围包括:
|
||
|
||
- 登录与登出
|
||
- 角色管理
|
||
- 口令变更
|
||
- UKey 管理
|
||
- 初始化与重置
|
||
- 升级与回滚
|
||
- 网络配置
|
||
- 白名单变更
|
||
- 密钥与密码卡操作
|
||
- 安全拦截事件
|
||
|
||
## 10. 推荐实现顺序
|
||
|
||
1. Flyway 建表,删除旧 `tms_auth_audit_log` / `tms_security_event`
|
||
2. 增加枚举、Entity、Repository
|
||
3. 增加 `OperationAuditSigner`(SM3 / SM2)
|
||
4. 增加 `OperationAuditService`
|
||
5. 增加 `@AuditedOperation` 与 AOP
|
||
6. 增加分页查询与详情接口
|
||
7. 增加审计接口
|
||
8. 在首批敏感接口上补齐注解与摘要
|