# 管理员操作审计功能设计 ## 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. 在首批敏感接口上补齐注解与摘要