549 lines
23 KiB
Markdown
549 lines
23 KiB
Markdown
|
||
# TMS Framework
|
||
|
||
Single-process TMS monolith scaffold built with:
|
||
- JDK 17
|
||
- Spring Boot 3.5.x
|
||
- MyBatis-Plus
|
||
- TiDB (MySQL driver)
|
||
- Swagger (springdoc-openapi)
|
||
|
||
## Quick Start
|
||
|
||
```bash
|
||
cd tms-framework
|
||
mvn spring-boot:run
|
||
```
|
||
|
||
## Jar 包部署(外置配置)
|
||
|
||
完整部署手册:
|
||
- [docs/deployment/tms-deployment.md](/Users/waner/Work/CISD/文档/tms-framework/docs/deployment/tms-deployment.md)
|
||
|
||
1. 构建 jar 包:
|
||
|
||
```bash
|
||
cd tms-framework
|
||
mvn -q -DskipTests package
|
||
cp target/tms-framework-*.jar /home/tms/tms-framework.jar
|
||
```
|
||
|
||
2. 在 CentOS 上准备部署目录:
|
||
|
||
```bash
|
||
sudo mkdir -p /home/tms/{bin,config,scripts,logs,run}
|
||
sudo mkdir -p /home/tms/bin/resource-restore
|
||
sudo chown -R "$(whoami)":"$(whoami)" /home/tms
|
||
cp scripts/tms.sh /home/tms/scripts/tms.sh
|
||
cp scripts/standard-init/*.sh /home/tms/bin/
|
||
cp scripts/resource-restore/*.sh /home/tms/bin/resource-restore/
|
||
cp config/application.yml.example /home/tms/config/application.yml
|
||
chmod +x /home/tms/bin/*.sh
|
||
chmod +x /home/tms/bin/resource-restore/*.sh
|
||
chmod +x /home/tms/scripts/tms.sh
|
||
```
|
||
|
||
3. 启动 / 停止 / 状态:
|
||
|
||
```bash
|
||
/home/tms/scripts/tms.sh start
|
||
/home/tms/scripts/tms.sh status
|
||
/home/tms/scripts/tms.sh stop
|
||
```
|
||
|
||
说明:
|
||
- 脚本默认 `APP_HOME=/home/tms`,并通过 `--spring.config.additional-location=optional:file:<app_home>/config/` 从 `/home/tms/config/` 读取外部配置。
|
||
- 默认要求 `/home/tms/config/application.yml` 存在。
|
||
- 脚本不再强制指定 profile;默认按 Spring 配置文件自身规则解析,可通过 `SPRING_PROFILES_ACTIVE=dev /home/tms/scripts/tms.sh start` 显式覆盖。
|
||
- 可通过 `JAR_PATH=/home/tms/tms-framework.jar` 覆盖 jar 路径。
|
||
- 如果部署路径不是 `/home/tms`,使用 `APP_HOME=/your/path /your/path/scripts/tms.sh start`。
|
||
- 标准 CISD 初始化辅助脚本位于 `scripts/standard-init/`,部署时需复制到 `/home/tms/bin/`。
|
||
- 资源恢复辅助脚本位于 `scripts/resource-restore/`,部署时需复制到 `/home/tms/bin/resource-restore/`。
|
||
- `apply_standard_db.sh` 依赖预置环境变量,例如 `DB_USER`、`DB_PASSWORD`,不要直接写入 `application.yml`。
|
||
- 运行目录结构、配置项说明、文件上传 `fileId` 流程和故障排查,请查看上面的完整部署手册。
|
||
|
||
运行时建议:
|
||
- 本地构建和测试统一使用 JDK 17,与项目和 CI 运行时保持一致。
|
||
|
||
Open:
|
||
- Swagger UI: http://localhost:8080/swagger-ui.html
|
||
- Internal API docs JSON: http://localhost:8080/v3/api-docs/internal-api
|
||
- Runtime-generated Swagger/OpenAPI docs are the source of truth for `/api/**`.
|
||
- Internal health API: `GET /api/v1/device/status`
|
||
- Internal sign preview API: `POST /api/v1/sign/preview`
|
||
- External sign API: `POST /openapi/v1/sign/signature`
|
||
- Init template API: `GET /api/v1/init/template`
|
||
- Init preview API: `POST /api/v1/init/preview`
|
||
- Current init config API: `GET /api/v1/init/config`
|
||
- Reset preview API: `POST /api/v1/init/reset/preview`
|
||
- Reset create task API: `POST /api/v1/init/reset/tasks`
|
||
- Reset execute API: `POST /api/v1/init/reset/tasks/{taskId}/execute`
|
||
- Auth login API: `POST /api/v1/auth/login`
|
||
- Compat password login API: `POST /api/v1/auth/password-login`
|
||
- Compat UKey login API: `POST /api/v1/auth/ukey-login`
|
||
- Compat UKey random API: `GET /api/v1/auth/ukey-login/randoms`
|
||
- UKey binding issue-sign API: `POST /api/v1/auth/roles/{roleCode}/ukeys/issue-sign`
|
||
- UKey binding API: `POST /api/v1/auth/roles/{roleCode}/ukeys/bind`
|
||
- Device info API: `GET /api/v1/device/info`
|
||
- Device profile API: `GET /api/v1/device/profile`
|
||
- Device runtime status API: `GET /api/v1/device/runtime-status`
|
||
- Upgrade package upload API: `POST /api/v1/upgrade-packages`
|
||
- Upgrade preview API: `POST /api/v1/upgrades/previews`
|
||
- Upgrade create task API: `POST /api/v1/upgrades`
|
||
- Upgrade execute API: `POST /api/v1/upgrades/{taskId}/execute`
|
||
- Upgrade list API: `GET /api/v1/upgrades`
|
||
- CRL import API: `POST /api/v1/crls/import`
|
||
- CRL import task detail API: `POST /api/v1/crls/import-tasks/detail`
|
||
- CRL revoked list API: `POST /api/v1/crls/list`
|
||
- CRL delete API: `POST /api/v1/crls/delete`
|
||
- PCIe crypto count API: `GET /api/v1/device/crypto/device-count`
|
||
- PCIe crypto HMAC API: `POST /api/v1/device/crypto/hmac`
|
||
|
||
## Certificate CRL Management
|
||
|
||
前后端对接文档:
|
||
- [docs/openapi/certificate-frontend-integration.md](/Users/waner/Work/CISD/文档/tms-framework/docs/openapi/certificate-frontend-integration.md)
|
||
|
||
最小调用顺序:
|
||
- `POST /api/v1/crls/import`
|
||
- `POST /api/v1/crls/list`
|
||
- `POST /api/v1/crls/delete`
|
||
|
||
当前实现边界:
|
||
- 可通过 `tms.cert.trusted-root-fingerprints` 配置根 CA 证书 SHA-256 指纹白名单;配置后根 CA 导入必须命中白名单,中间 CA 仍按当前可信链校验。
|
||
- CRL 文件支持 PEM / DER 格式,导入接口会先创建后台任务并返回 `taskId`,前端通过 `POST /api/v1/crls/import-tasks/detail` 轮询 `PENDING/RUNNING/SUCCESS/FAILED` 状态。
|
||
- 后台导入完成后保存 CRL metadata 和 CRL 内每条 revoked certificate 明细;原始 CRL 文件只作为临时文件参与解析,任务结束后删除,不作为业务数据长期保存。
|
||
- CRL issuer 通过可信 CA 的 issuer DN 候选和实际 CRL 签名验证解析。
|
||
- CRL issuer 必须是可信 CA,且 KeyUsage 必须允许 `cRLSign`。
|
||
- 重复 CRL 通过 SHA-256 fingerprint 拒绝。
|
||
- revoked 明细查询按 `algoType` 和证书 `subjectDn` 模糊过滤,返回的是 revoked certificate 明细列表,不是 CRL 文件列表。
|
||
- 证书导入时如果 `issuerDn + serialNumber` 已命中已导入 CRL,会拒绝导入。
|
||
- 证书列表和详情的 `runtimeStatus` 在 CRL 命中时优先返回 `REVOKED`,优先级高于时间有效期状态。
|
||
|
||
## CISD Reset
|
||
|
||
最小调用顺序:
|
||
- `POST /api/v1/init/reset/preview`
|
||
- `POST /api/v1/init/reset/tasks`
|
||
- `POST /api/v1/init/reset/tasks/{taskId}/execute`
|
||
- `GET /api/v1/init/reset/tasks/{taskId}`
|
||
- `GET /api/v1/init/reset/tasks/{taskId}/steps`
|
||
- `GET /api/v1/init/reset/tasks/{taskId}/steps/{stepNo}/log`
|
||
|
||
当前支持范围:
|
||
- 仅支持设备预置产品类型为 `ENTERPRISE` 或 `INDIRECT`
|
||
- `DIRECT` 当前明确不支持 reset
|
||
|
||
请求说明:
|
||
- reset 接口不再要求前端重复提交机构号、MQ 类型和 RabbitMQ 通道用户
|
||
- 后端会自动读取“最近一次成功初始化任务”的快照,提取 `orgCode`、`mqType`、`channelUsername`
|
||
- 如果当前设备没有有效初始化快照,reset 预检和任务创建会直接失败
|
||
|
||
设备状态接口:
|
||
- `GET /api/v1/device/status`
|
||
- 返回字段 `initState`
|
||
- `UNINITIALIZED`: 当前没有有效初始化快照
|
||
- `INITIALIZING`: 初始化任务正在执行
|
||
- `INITIALIZED`: 当前设备已初始化
|
||
- `RESETTING`: 重置任务正在执行
|
||
- 前端仅根据 `initState` 判断展示初始化页、已初始化页或执行中页面
|
||
|
||
当前初始化配置展示接口:
|
||
- `GET /api/v1/init/config`
|
||
- 数据来源固定为最新一次成功初始化任务快照
|
||
- 只返回机构信息、部署信息、中间件信息和节点/签名核心字段
|
||
- 只用于展示,不用于编辑
|
||
|
||
当前 reset 实际会做的事情:
|
||
- 停止 `CMSP/CMTP`
|
||
- 删除数据库 `CMEP`
|
||
- 删除数据库 `orgCode`
|
||
- 删除 RabbitMQ 客户化账号、`/RQ` 权限、客户化队列
|
||
- 停止 RabbitMQ 进程
|
||
- 删除 TLQ license 文件
|
||
- 清理当前 reset 任务的 staging 目录
|
||
|
||
当前 reset 不做的事情:
|
||
- 不回滚 `cpconfig.cfg`
|
||
- 不删除 nginx 配置和已发布前端目录
|
||
- 不回滚应用配置文件中的 RabbitMQ 账号密码
|
||
- 不删除标准安装介质目录
|
||
|
||
运维前置条件:
|
||
- `scripts/standard-init/*.sh` 已部署到 `/home/tms/bin/`
|
||
- `/home/tms/bin/stop_standard_apps.sh`
|
||
- `/home/tms/bin/stop_standard_rabbitmq.sh`
|
||
- `/home/tms/bin/apply_standard_db.sh`
|
||
- `tms.init.executor.standard-db-username/password` 已正确配置
|
||
- `tms.init.executor.rabbitmq-ctl-command` 指向可执行的 `rabbitmqctl`
|
||
- 运行时 Swagger 文档以 `http://<ip>:8080/swagger-ui.html` 和 `http://<ip>:8080/v3/api-docs/internal-api` 为准
|
||
|
||
## Offline Upgrade
|
||
|
||
最小调用顺序:
|
||
- `POST /api/v1/upgrade-packages`
|
||
- `POST /api/v1/upgrades/previews`
|
||
- `POST /api/v1/upgrades`
|
||
- `POST /api/v1/upgrades/{taskId}/execute`
|
||
- `POST /api/v1/upgrades/{taskId}/rollback`
|
||
- `GET /api/v1/upgrades`
|
||
- `GET /api/v1/upgrades/{taskId}`
|
||
- `GET /api/v1/upgrades/{taskId}/log`
|
||
|
||
当前支持范围:
|
||
- 仅支持离线升级
|
||
- 当前支持任务类型:
|
||
- `TMS`
|
||
- `RECEIVER`
|
||
- `FIRMWARE`
|
||
- 当前不支持:
|
||
- 在线升级
|
||
- `CVE` / 操作系统补丁升级
|
||
|
||
当前流程:
|
||
- 先上传离线升级包,复用现有文件上传能力,得到 `fileId`
|
||
- 后端基于 `fileId` 解析升级包并做预检
|
||
- 预检结果返回 `taskType`、`productType`、当前版本、目标版本和版本变化提示
|
||
- 用户确认后创建升级任务
|
||
- 调用执行接口后,任务异步进入后台执行
|
||
- 升级失败后,如升级包提供 `rollback` 入口,可手工调用回滚接口
|
||
- 前端通过列表、详情和日志接口轮询任务状态
|
||
|
||
当前升级包要求:
|
||
- 外层为 zip 包
|
||
- 至少包含:
|
||
- `manifest.json`
|
||
- `signature.sig`
|
||
- `payload/` 下按需包含:
|
||
- `app/`
|
||
- `web/dist/`
|
||
- `config/`
|
||
- `sql/`
|
||
- `firmware/`
|
||
- `scripts/`
|
||
- 外层升级包实际包含的是 `payload.zip`,`payload.zip` 内部再包含上述 `payload/` 目录
|
||
- `signature.sig` 需要能被配置的 PEM 公钥使用 `SM3withSM2` 软验签通过
|
||
- 服务端需要配置 `tms.upgrade.signature-public-key-pem-path`(公钥 PEM 文件路径)
|
||
- `manifest.json` 当前要求包含:
|
||
- `packageId`
|
||
- `taskType`
|
||
- `productType`
|
||
- `version`
|
||
- `minCompatibleVersion`
|
||
- `description`
|
||
- `entrypoints.execute`
|
||
- `payloadSm3`
|
||
- 可选 `entrypoints.precheck`
|
||
- 可选 `entrypoints.verify`
|
||
- 可选 `entrypoints.rollback`
|
||
- `payloadSm3` 是整个 `payload.zip` 文件的 `SM3` 摘要;后端验签 `manifest.json` 后,会校验 `payload.zip` 摘要并解压出 `payload/` 供脚本执行
|
||
|
||
当前执行规则:
|
||
- 同一时刻只允许一个升级任务处于 `RUNNING`
|
||
- 不允许目标版本低于当前版本
|
||
- 不满足最小兼容版本时拒绝升级
|
||
- `execute.sh` 必填,`precheck.sh`、`verify.sh`、`rollback.sh` 可选
|
||
- 执行顺序为:`precheck -> execute -> verify`
|
||
- `TMS` 自升级包内脚本第一版不应直接 `stop/start` 当前 TMS;推荐只完成文件准备,由后端在写入终态和日志后异步触发 `/home/tms/scripts/tms.sh restart`
|
||
- `FIRMWARE` 不增加额外后端流程,具体固件刷写、重启、恢复提示由包内脚本负责
|
||
- 回滚不自动触发,需要调用回滚接口
|
||
- `TMS`、`RECEIVER` 升级成功后会更新 `tms_device_software_version`;`FIRMWARE` 暂不维护版本表
|
||
|
||
## Resource Backup / Restore
|
||
|
||
最小调用顺序:
|
||
- `POST /api/v1/resource-backups`
|
||
- `GET /api/v1/resource-backups/{taskId}`
|
||
- `GET /api/v1/resource-backups/{taskId}/download`
|
||
- `POST /api/v1/resource-restores/precheck`
|
||
- `POST /api/v1/resource-restores`
|
||
- `POST /api/v1/resource-restores/{taskId}/apply`
|
||
- `GET /api/v1/resource-restores/latest`
|
||
|
||
恢复任务创建接口只完成验签、解密、展开和计划生成;前端只做一次“确认恢复”,确认后先调用创建接口,返回 `READY_TO_APPLY` 后立即调用 apply 接口进入停机恢复。也就是用户确认后调用 apply 接口进入停机恢复,不再做第二次确认。TMS 重启后前端可调用 latest 接口展示最近一次恢复时间、结果和失败原因。
|
||
|
||
前后端字段、状态枚举和联调流程见 `docs/openapi/resource-backup-restore-frontend-integration.md`。
|
||
|
||
当前实现边界:
|
||
- 资源备份包输出为 `.tmsbak`,包内包含 `manifest.json`、`envelope.json`、`payload.enc`、`signature.sig`
|
||
- `payload.enc` 加解密使用 PCIe 密码卡 SDF 会话密钥流程:备份时通过 `SDF_GenerateKeyWithIPK_ECC` 生成内部 ECC 公钥包裹的会话密钥并用 `SDF_Encrypt` 加密 payload;恢复时通过 `SDF_ImportKeyWithISK_ECC` 导入包裹会话密钥并用 `SDF_Decrypt` 解密 payload。`envelope.json` 保持 `version=1`,只记录 `payloadAlg`、`ivBase64` 和 `wrappedSessionKeyBase64`,`keyIndex/keyBits/algId` 由系统固定约定。
|
||
- 当前第一版备份/恢复只覆盖最小资源集:
|
||
- `TMS_CONFIG`
|
||
- `TMS_DB`
|
||
- `CMEP_DB`
|
||
- `ORG_DB`(标准/间参收发器以 `orgCode` 命名的机构业务库;`DIRECT` 模式不包含)
|
||
- `CP_CONFIG`
|
||
- `RECEIVER_LICENSE`
|
||
- `STANDARD_CMSP_APP_CONFIG`(标准版 CMSP 应用配置,由默认 `tms.backup.file-resources` 配置匹配 `/home/cmep4i/cmsp/application-prd*.properties`)
|
||
- `STANDARD_CMTP_APP_CONFIG`(标准版 CMTP 应用配置,由默认 `tms.backup.file-resources` 配置匹配 `/home/cmep4i/cmtp/application-prd*.properties`)
|
||
- `USER_KEY`(从实体证书 `KeyEntity.keyIdx` 采集用户密钥备份)
|
||
- `MQ_REPLAY`
|
||
- 预检阶段只做包头解析、指纹匹配和验签,不提前解密完整 payload
|
||
- 恢复任务创建时 Java 完成验签、PCIe/SDF 解密、payload 展开、用户密钥恢复和恢复路径白名单校验
|
||
- Java 会生成 shell 友好的 `restore-files.tsv`、`restore-databases.tsv`、`restore-mq.tsv`
|
||
- 创建恢复任务后启动 `apply-resource-backup.sh --work-dir <workDir>`,由 shell 执行停服务、文件覆盖、SQL 导入、MQ replay、起服务和健康检查
|
||
- Java 启动恢复脚本前会在工作目录生成 `restore-env.sh`、`restore-stop-commands.tsv`、`restore-start-commands.tsv`;停启服务命令来自 `tms.backup.restore-stop-commands` / `tms.backup.restore-start-commands`
|
||
- 标准/间参默认恢复后会启动 TMS、CMSP/CMTP 和 nginx;现场需要启动其它软件时,只需在上述命令列表里增删配置项
|
||
- shell 侧状态写入 `status.json`,日志写入 `restore.log`
|
||
- 第一版资源恢复是停机恢复。创建恢复任务后当前TMS服务可能中断,前端应提示用户恢复期间页面/API可能不可用,恢复结果以后续健康检查、重新登录和 `status.json` / `restore.log` 为准。
|
||
- `FILE` 回写 manifest 明确声明的配置/License 文件
|
||
- 可通过 `tms.backup.file-resources` 自行增删直接复制恢复的文件类资源:
|
||
- `mode=FILE`:单文件,`restore-path` 是目标文件路径
|
||
- `mode=DIR`:目录递归,`restore-path` 是目标目录
|
||
- `mode=GLOB`:通配符匹配同一目录下的一批文件,`restore-path` 是目标目录
|
||
- `product-types` / `mq-types`:可选过滤条件;不配置表示所有产品类型或 MQ 类型都适用
|
||
- `required=true` 时匹配不到或读取失败会导致备份失败,`required=false` 时跳过并写入 manifest
|
||
- `DATABASE` 恢复:
|
||
- `db/TMS.sql`
|
||
- `db/CMEP.sql`(包内存在时)
|
||
- `db/<orgCode>.sql`(标准/间参收发器包内存在时,导回同名机构库)
|
||
- `TMS_DB` 备份默认通过 `tms.backup.tms-db-excluded-tables` 排除角色、授权、会话和审计表,恢复时不会覆盖新机器安全状态
|
||
- `MQ_REPLAY` 通过 `replay-mq.sh` 消费 `mq/mq-restore-context.json`,也可用 `MQ_REPLAY_COMMAND` 委派给现场脚本
|
||
- Java 启动恢复脚本前会在工作目录生成 `restore-env.sh`,传递数据库连接、恢复脚本路径、MQ replay 脚本路径和健康检查配置;健康检查会按配置重试等待 TMS 真正启动完成
|
||
|
||
关键配置:
|
||
- `tms.backup.output-dir`
|
||
- `tms.backup.precheck-store-dir`
|
||
- `tms.backup.restore-task-root-dir`
|
||
- `tms.backup.tms-script-path`
|
||
- `tms.backup.restore-stop-commands`
|
||
- `tms.backup.restore-start-commands`
|
||
- `tms.backup.restore-apply-script-path`
|
||
- `tms.backup.allowed-restore-roots`
|
||
- `tms.backup.file-resources`
|
||
- `tms.backup.mysqldump-path`
|
||
- `tms.backup.mysqldump-timeout-seconds`
|
||
- `tms.backup.mysql-path`
|
||
- `tms.backup.restore-db-script-path`
|
||
- `tms.backup.mq-replay-script-path`
|
||
- `tms.backup.tms-database-name`
|
||
- `tms.backup.tms-db-excluded-tables`
|
||
- `tms.backup.cmep-database-name`
|
||
- `tms.backup.health-check-url`
|
||
- `tms.backup.health-check-timeout-seconds`
|
||
- `tms.backup.health-check-max-wait-seconds`
|
||
- `tms.backup.health-check-retry-interval-seconds`
|
||
|
||
恢复前置条件:
|
||
- LMK、IK、数据存储加密密钥对、数据真实性保护密钥对需先通过 UKey 恢复
|
||
- `/home/tms/bin/resource-restore/apply-resource-backup.sh`、`restore-db.sh`、`replay-mq.sh` 必须已部署并可执行
|
||
- `mysql` / `mysqldump` 客户端必须可用
|
||
|
||
当前明确不在第一版恢复范围内:
|
||
- nginx 配置
|
||
- `organization.json`
|
||
- 已发布 web 静态资源
|
||
- `/home/tms/uploads`
|
||
- 机构库
|
||
- 在线恢复 / 增量恢复 / 回滚
|
||
- 升级执行日志统一写入 `tms.upgrade.log-dir`
|
||
|
||
联调清单:
|
||
- [资源备份恢复 V1 联调清单](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-04-18-resource-backup-restore-v1-checklist.md)
|
||
|
||
当前配置项:
|
||
- `tms.upgrade.staging-root-dir`
|
||
- `tms.upgrade.log-dir`
|
||
- `tms.upgrade.signature-public-key-pem-path`
|
||
|
||
升级包规范见:
|
||
- [2026-03-19-upgrade-package-spec.md](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-03-19-upgrade-package-spec.md)
|
||
- [标准收发器升级包最小样例](/Users/waner/Work/CISD/文档/tms-framework/docs/examples/upgrade-package/standard-app/README.md)
|
||
- [离线升级包预检联调清单与示例](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-03-19-upgrade-preview-integration-guide.md)
|
||
|
||
## Architecture (Monolith + Modular)
|
||
|
||
- One deployable Spring Boot application.
|
||
- Module-first packaging under `modules/*`.
|
||
- Default module layout: `controller + service + repository + entity + dto`.
|
||
- `sign` module has extra `controller/openapi`, `dto/openapi`, and `support`.
|
||
- Cross-cutting concerns moved to top-level `security` and `integration`.
|
||
|
||
## Project Structure
|
||
|
||
```text
|
||
src/main/java/com/cisd/tms
|
||
├── TmsApplication.java
|
||
├── common
|
||
│ ├── api
|
||
│ ├── config
|
||
│ │ └── properties
|
||
│ ├── constant
|
||
│ ├── enums
|
||
│ ├── exception
|
||
│ └── util
|
||
├── infrastructure
|
||
│ └── persistence
|
||
│ ├── entity
|
||
│ ├── mapper
|
||
│ └── mybatis
|
||
├── integration
|
||
│ ├── cips
|
||
│ ├── mq
|
||
│ ├── crypto
|
||
│ └── file
|
||
├── security
|
||
│ ├── internal
|
||
│ └── openapi
|
||
└── modules
|
||
├── system
|
||
│ ├── controller
|
||
│ ├── service
|
||
│ └── dto
|
||
├── sign
|
||
│ ├── controller
|
||
│ ├── controller/openapi
|
||
│ ├── service
|
||
│ ├── dto/internal
|
||
│ ├── dto/openapi
|
||
│ ├── support
|
||
│ ├── repository
|
||
│ └── entity
|
||
├── init
|
||
├── auth
|
||
|
||
## Auth Compat
|
||
|
||
当前仓库只包含后端认证接口,不包含登录页前端工程。
|
||
|
||
兼容旧管理端的登录调用说明见:
|
||
- [2026-03-23-auth-compat-integration-guide.md](/Users/waner/Work/CISD/文档/tms-framework/docs/plans/2026-03-23-auth-compat-integration-guide.md)
|
||
├── device
|
||
├── upgrade
|
||
├── cert
|
||
├── key
|
||
├── audit
|
||
├── backup
|
||
└── activation
|
||
```
|
||
|
||
```text
|
||
src/main/resources
|
||
├── application.yml
|
||
├── application-dev.yml
|
||
├── application-prod.yml
|
||
├── mapper
|
||
│ ├── init/InitTaskMapper.xml
|
||
│ ├── auth/AuthUserMapper.xml
|
||
│ └── device/DeviceNodeMapper.xml
|
||
└── db/migration
|
||
└── V1__init_auth_device_tables.sql
|
||
```
|
||
|
||
## API Boundary Rules
|
||
|
||
- `/api/**` controllers live under `controller`.
|
||
- External API controllers only in `*/controller/openapi`, path prefix `/openapi/**`.
|
||
- Internal and external DTOs are separated.
|
||
- Cross-module calls must go through `service`, not `repository`.
|
||
- Internal token interceptor exclusions: `/api/v1/device/status`, `/api/v1/auth/login`.
|
||
|
||
## Auth Configuration
|
||
|
||
```yaml
|
||
tms:
|
||
security:
|
||
internal-token: ${TMS_INTERNAL_TOKEN:change-me-internal-token}
|
||
openapi:
|
||
timestamp-skew-seconds: 300
|
||
clients:
|
||
demo-app: ${TMS_OPENAPI_DEMO_SECRET:change-me-openapi-secret}
|
||
```
|
||
|
||
## Crypto Card Configuration
|
||
|
||
```yaml
|
||
tms:
|
||
crypto-card:
|
||
enabled: ${TMS_CRYPTO_CARD_ENABLED:false}
|
||
mode: ${TMS_CRYPTO_CARD_MODE:MOCK} # MOCK / JNA
|
||
vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:/home/tms/libs/libsdf_ukey_syd1408-x64.so.1.0.0}
|
||
vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:sdf_ukey_syd1408}
|
||
```
|
||
|
||
- Internal PCIe debug APIs (strong-typed service):
|
||
- `GET /api/v1/device/crypto/device-count`
|
||
- `GET /api/v1/device/crypto/device-conf`
|
||
- `GET /api/v1/device/crypto/device-info`
|
||
- `GET /api/v1/device/crypto/random?length=16`
|
||
- `POST /api/v1/device/crypto/self-test`
|
||
- `POST /api/v1/device/crypto/hmac`
|
||
- `POST /api/v1/device/crypto/digest`
|
||
- `POST /api/v1/device/crypto/encrypt/plain`
|
||
- `POST /api/v1/device/crypto/decrypt/plain`
|
||
- `POST /api/v1/device/crypto/encrypt/kek`
|
||
- `POST /api/v1/device/crypto/decrypt/kek`
|
||
- `POST /api/v1/device/crypto/mac/plain`
|
||
- `POST /api/v1/device/crypto/file/create`
|
||
- `POST /api/v1/device/crypto/file/write`
|
||
- `POST /api/v1/device/crypto/file/read`
|
||
- `POST /api/v1/device/crypto/file/delete`
|
||
- `POST /api/v1/device/crypto/kek/generate`
|
||
- `GET /api/v1/device/crypto/kek/status?keyIndex=1`
|
||
- `GET /api/v1/device/crypto/lmk/seed-mac`
|
||
- `POST /api/v1/device/crypto/std/keypair/rsa`
|
||
- `POST /api/v1/device/crypto/std/keypair/ecc`
|
||
- `POST /api/v1/device/crypto/envelope/exchange/rsa`
|
||
- `POST /api/v1/device/crypto/envelope/exchange/ecc`
|
||
- `POST /api/v1/device/crypto/agreement/data-key/ecc`
|
||
- `POST /api/v1/device/crypto/agreement/session-key/ecc`
|
||
|
||
## PCIe Crypto Unified Wrapper (JNA)
|
||
|
||
The project keeps JNA native mappings for PCIe card `SDF/SDFE` interfaces from
|
||
`PCIE密码卡应用接口说明书 V1.02`, and provides strong-typed service APIs via
|
||
`com.cisd.tms.integration.crypto.pcie.service.PcieCryptoService`.
|
||
|
||
```yaml
|
||
tms:
|
||
crypto-card:
|
||
enabled: ${TMS_CRYPTO_CARD_ENABLED:false}
|
||
mode: ${TMS_CRYPTO_CARD_MODE:JNA} # MOCK / JNA
|
||
vendor-lib-path: ${TMS_CRYPTO_VENDOR_LIB_PATH:/home/tms/libs/libsdf_ukey_syd1408-x64.so.1.0.0}
|
||
vendor-lib-name: ${TMS_CRYPTO_VENDOR_LIB_NAME:sdf_ukey_syd1408}
|
||
```
|
||
|
||
- JNA native mapping: `com.cisd.tms.integration.crypto.pcie.jna.PcieNativeLibrary`
|
||
- JNA implementation: `com.cisd.tms.integration.crypto.pcie.service.JnaPcieCryptoService`
|
||
- Mock fallback: `com.cisd.tms.integration.crypto.pcie.service.MockPcieCryptoService`
|
||
|
||
### OpenAPI Signature Rules
|
||
|
||
- Headers: `X-App-Id`, `X-Timestamp`, `X-Nonce`, `X-Signature`
|
||
- Canonical string: `appId + "\\n" + timestamp + "\\n" + nonce`
|
||
- Signature algorithm: `HMAC-SHA256` with app secret, lowercase hex
|
||
- Replay protection: nonce one-time in time window
|
||
|
||
## Build And Test
|
||
|
||
```bash
|
||
mvn -q -DskipTests compile
|
||
mvn -q test
|
||
```
|
||
|
||
## PCIe Real-Card Smoke
|
||
|
||
- Checklist: `docs/plans/2026-02-28-pcie-realcard-smoke-checklist.md`
|
||
- Script template: `scripts/pcie_realcard_smoke.sh`
|
||
|
||
Example:
|
||
|
||
```bash
|
||
export BASE_URL=http://127.0.0.1:8080
|
||
export INTERNAL_TOKEN=change-me-internal-token
|
||
export ALG_SM3=1
|
||
export ALG_SM4_ECB=1025
|
||
./scripts/pcie_realcard_smoke.sh
|
||
```
|
||
|
||
- CI is pinned to JDK 17 via `.github/workflows/ci.yml`.
|
||
- Maven Surefire preloads Mockito javaagent to avoid dynamic self-attach failures on newer JDKs.
|
||
|
||
## Current Status
|
||
|
||
- Structure refactored to lightweight monolith modules.
|
||
- Internal and external API entry points separated.
|
||
- Basic auth interceptors for internal/openapi are in place.
|
||
- `init/auth/device/sign/system` modules have runnable skeleton controllers and services.
|
||
- `init/auth/device` modules include mapper+xml+repository-impl+DDL skeleton for TiDB.
|