# License签名验证问题修复总结 ## 问题描述 在项目中出现License签名验证失败的问题,根本原因是`YudaoJacksonAutoConfiguration`中配置的全局`LocalDateTime`序列化器与`LicenseGenerator`中的序列化配置不一致。 ## 问题根本原因 1. **YudaoJacksonAutoConfiguration配置**:使用`TimestampLocalDateTimeSerializer`将`LocalDateTime`序列化为时间戳(Long类型) 2. **LicenseGenerator原始配置**:使用标准Jackson配置,禁用`WRITE_DATES_AS_TIMESTAMPS`,将`LocalDateTime`序列化为ISO格式字符串 3. **签名数据不一致**:两种不同的时间格式导致签名数据字符串不同,进而导致签名验证失败 ## 修复方案 ### 1. 统一LicenseGenerator的序列化配置 修改`LicenseGenerator`构造函数,使其与项目的全局配置保持一致: ```java public LicenseGenerator() { this.objectMapper = new ObjectMapper(); this.objectMapper.registerModule(new JavaTimeModule()); // 使用与项目一致的LocalDateTime序列化配置,确保签名数据一致性 SimpleModule simpleModule = new SimpleModule(); simpleModule.addSerializer(LocalDateTime.class, TimestampLocalDateTimeSerializer.INSTANCE); simpleModule.addDeserializer(LocalDateTime.class, TimestampLocalDateTimeDeserializer.INSTANCE); this.objectMapper.registerModule(simpleModule); this.objectMapper.enable(SerializationFeature.INDENT_OUTPUT); } ``` ### 2. 修改签名数据生成逻辑 更新`appendField`方法,确保时间字段在签名数据中也使用时间戳格式: ```java private void appendField(StringBuilder sb, String fieldName, Object value) { sb.append(fieldName).append("="); if (value != null) { // 对LocalDateTime字段使用时间戳格式,确保与JSON序列化一致 if (value instanceof LocalDateTime) { LocalDateTime dateTime = (LocalDateTime) value; long timestamp = dateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(); sb.append(timestamp); } else { sb.append(value.toString()); } } sb.append(";"); } ``` ## 修复验证 ### 测试结果 运行`LicenseSignatureTest`验证修复效果: ``` === 序列化结果比较 === 序列化结果是否一致: ✓ 是 === 时间字段格式测试 === 原始LocalDateTime: 2025-08-13T00:54:47.875317500 toString()格式: 2025-08-13T00:54:47.875317500 时间戳格式: 1755017687875 JSON序列化: 1755017687875 === 签名数据生成测试 === 生成的签名数据: licenseId=TEST-LICENSE-001;customerName=测试客户;productName=测试产品;productVersion=1.0.0;createdTime=1755017687875;startTime=1755017687875;endTime=1757609687875;strategy=GRACEFUL_SHUTDOWN;gracePeriodDays=;warningDays=;maxUsers=100; === 测试完成 === 结论: 修复成功,时间序列化格式已统一 ``` ### 关键验证点 1. ✅ **JSON序列化一致性**:LicenseGenerator和项目配置的序列化结果完全一致 2. ✅ **时间格式统一**:所有时间字段都使用时间戳格式(1755017687875) 3. ✅ **签名数据格式**:签名数据中的时间字段也使用时间戳格式 ## 修复的文件 1. **LicenseGenerator.java** - 添加了与项目一致的LocalDateTime序列化配置 - 修改了appendField方法以处理LocalDateTime字段 2. **新增文件** - `LICENSE_SIGNATURE_ISSUE_SOLUTION.md`:问题分析和解决方案文档 - `LicenseSignatureTest.java`:签名一致性测试工具 - `SIGNATURE_FIX_SUMMARY.md`:修复总结文档 ## 后续建议 1. **重新生成License文件**:使用修复后的LicenseGenerator重新生成所有现有的License文件 2. **集成测试**:在实际环境中测试License的生成和验证流程 3. **文档更新**:更新License生成和使用的相关文档 4. **监控机制**:建立License验证的监控和告警机制 ## 预防措施 1. 建立License生成和验证的自动化测试 2. 在CI/CD流程中加入License兼容性检查 3. 统一项目中所有时间序列化的配置标准 4. 定期检查Jackson配置变更对License系统的影响 --- **修复状态**: ✅ 已完成 **验证状态**: ✅ 已通过 **修复时间**: 2025-08-13