
Spring Boot项目中使用 TrueLicense 生成和验证License(服务器许可)
发布日期:2021-05-12 23:54:48
浏览次数:33
分类:精选文章
本文共 12878 字,大约阅读时间需要 42 分钟。
在Spring Boot项目中集成TrueLicense生成并验证服务器许可证,可以按照以下步骤实施:
1. 加载TrueLicense依赖
在项目的pom.xml
中添加TrueLicense的依赖:
de.schlichtherle.truelicense truelicense-core 1.33 provided
2. 配置生成许可证的参数
创建LicenseParam
类,配置所有需要的参数:
package com.example.license;import com.fasterxml.jackson.databind.annotation.JsonFormat;import java.io.Serializable;import java.util.Date;public class LicenseParam implements Serializable { private static final long serialVersionUID = -7793154252684580872L; private String subject; private String privateAlias; private String keyPass; private String storePass; private String licensePath; private String privateKeysStorePath; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date issuedTime = new Date(); @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private Date expiryTime; private String consumerType = "user"; private Integer consumerAmount = 1; private String description; private LicenseCheckModel licenseCheckModel; // setter和getter方法}
3. 创建自定义的硬件信息校验模型
定义LicenseCheckModel
类,添加所需校验的硬件信息:
package com.example.license;import java.io.Serializable;import java.util.List;public class LicenseCheckModel implements Serializable { private static final long serialVersionUID = 8600137500316662317L; private ListipAddress; private List macAddress; private String cpuSerial; private String mainBoardSerial; // setter和getter方法}
4. 自定义LicenseManager进行自定义校验
继承LicenseManager
并复写必要的方法:
public class CustomLicenseManager extends LicenseManager { public CustomLicenseManager() { super(); } @Override protected LicenseContent create(LicenseContent content, LicenseNotary notary) throws Exception { initialize(content); this.validateCreate(content); final GenericCertificate certificate = notary.sign(content); return getPrivacyGuard().cert2key(certificate); } @Override protected void validate(LicenseContent content) throws LicenseContentException { super.validate(content); LicenseCheckModel expectedModel = (LicenseCheckModel) content.getExtra(); LicenseCheckModel serverModel = new LinuxServerInfos().getServerInfos(); if (expectedModel != null && serverModel != null) { if (!checkIpAddress(expectedModel.ipAddress, serverModel.ipAddress)) { throw new LicenseContentException("IP不在授权范围内"); } if (!checkIpAddress(expectedModel.macAddress, serverModel.macAddress)) { throw new LicenseContentException("MAC地址不在授权范围内"); } if (!checkSerial(expectedModel.cpuSerial, serverModel.cpuSerial)) { throw new LicenseContentException("CPU序列号不在授权范围内"); } if (!checkSerial(expectedModel.mainBoardSerial, serverModel.mainBoardSerial)) { throw new LicenseContentException("主板序列号不在授权范围内"); } } else { throw new LicenseContentException("无法获取服务器硬件信息"); } } private boolean checkIpAddress(Listexpected, List server) { if (server != null && expected != null) { for (String exp : expected) { if (server.contains(exp.trim())) { return true; } } } return false; } private boolean checkSerial(String expected, String server) { if (StringUtils.isNotBlank(expected) && StringUtils.isNotBlank(server)) { return expected.trim().equals(server.trim()); } return false; }}
5. 生成许可证文件
创建LicenseCreator
类,负责生成许可证文件:
public class LicenseCreator { private LicenseCreatorParam param; public LicenseCreator(LicenseCreatorParam param) { this.param = param; } public boolean generateLicense() { try { CustomLicenseManager licenseManager = new CustomLicenseManager(initLicenseParam()); LicenseContent licenseContent = initLicenseContent(); licenseManager.store(licenseContent, new File(param.getLicensePath())); return true; } catch (Exception e) { logger.error("证书生成失败:" + param.toString(), e); return false; } } private LicenseParam initLicenseParam() { Preferences preferences = Preferences.userNodeForPackage(LicenseCreator.class); CipherParam cipherParam = new DefaultCipherParam(param.getStorePass()); KeyStoreParam keyStoreParam = new CustomKeyStoreParam(LicenseCreator.class, param.getPrivateKeysStorePath(), param.getPrivateAlias(), param.getStorePass(), param.getKeyPass()); return new DefaultLicenseParam(param.getSubject(), preferences, keyStoreParam, cipherParam); } private LicenseContent initLicenseContent() { LicenseContent content = new LicenseContent(); content.setHolder(DEFAULT_HOLDER_AND_ISSUER); content.setIssuer(DEFAULT_HOLDER_and_ISSUER); content.setSubject(param.getSubject()); content.setIssued(param.getIssuedTime()); content.setNotBefore(param.getIssuedTime()); content.setNotAfter(param.getExpiryTime()); content.setConsumerType(param.getConsumerType()); content.setConsumerAmount(param.getConsumerAmount()); content.setDescription(param.getDescription()); content.setExtra(param.getLicenseCheckModel()); return content; } // 其他代码}
6. 创建生成许可证的接口
定义一个LicenseCreatorController
,提供RESTful接口:
@RestControllerpublic class LicenseCreatorController { @Value("${license.licensePath}") private String licensePath; @RequestMapping(value = "/generateLicense", produces = MediaType.APPLICATION_JSON_VALUE) public MapgenerateLicense(@RequestBody LicenseCreatorParam param) { Map result = new HashMap<>(); if (StringUtils.isBlank(param.getLicensePath())) { param.setLicensePath(licensePath); } LicenseCreator licenseCreator = new LicenseCreator(param); boolean success = licenseCreator.generateLicense(); if (success) { result.put("status", "ok"); result.put("message", "许可证已成功生成,请检查生成路径:" + param.getLicensePath()); } else { result.put("status", "error"); result.put("message", "许可证文件生成失败,请检查日志或参数配置"); } return result; }}
7. 部署测试项目并生成许可证
部署测试项目ServerDemo
,通过API接口获取硬件信息并生成许可证:
@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}@RestControllerpublic class LicenseGeneratorController { @Value("${license.licenseTempPath}") private String licenseTempPath; @Value("${license.hardwareInfoUrl}") private String hardwareInfoUrl; @GetMapping("/getHardwareInfo") public LicenseCheckModel getHardwareInfo(@RequestParam(required = false, name = "osName") String osName) { if (StringUtils.isBlank(osName)) { osName = System.getProperty("os.name").toLowerCase(); } String пласти,也就是硬件信息集合. AbstractServerInfos serverInfos = new LinuxServerInfos(); return serverInfos.getServerInfos(); } @PostMapping("/generate") public Mapgenerate(@RequestBody LicenseCreatorParam param) { Map result = new HashMap<>(); if (StringUtils.isBlank(param.getLicensePath())) { param.setLicensePath(licenseTempPath); } LicenseCreator licenseCreator = new LicenseCreator(param); boolean success = licenseCreator.generateLicense(); if (success) { result.put("status", "success"); result.put("message", "许可证已生成,路径为:" + param.getLicensePath()); } else { result.put("status", "error"); result.put("message", "许可证生成失败,请检查配置"); } return result; }}
8. 集成许可证校验
创建LicenseVerify
类,负责校验许可证并安装:
public class LicenseVerify { public LicenseVerify() { super(); } public LicenseContent install(LicenseVerifyParam param) throws Exception { LicenseManager manager = LicenseManagerHolder.getInstance(formatParameters(param)); manager.uninstall(); LicenseContent content = manager.install(new File(param.getLicensePath())); logger.info(" Installed successfully, valid until: {}, expires at: {}", content.getNotBefore(), content.getNotAfter()); return content; } public boolean verify() { LicenseManager manager = LicenseManagerHolder.getInstance(null); try { LicenseContent content = manager.verify(); logger.info(" Verified successfully; valid until: {}, expires at: {}", content.getNotBefore(), content.getNotAfter()); return true; } catch (Exception e) { logger.error("Verification failed!", e); return false; } } private LicenseParam formatParameters(LicenseVerifyParam param) { return new DefaultLicenseParam( param.getSubject(), preferences, keyStoreParam, cipherParam ); }}
9. 自动安装许可证
创建LicenseCheckListener
,在项目启动时安装许可证:
@SpringBootApplicationpublic class LicenseApplication extends Application { public static void main(String[] args) { SpringApplication.run(LicenseApplication.class, args); } @Value("${license.clientОВерID_BOOL}") private boolean enabled; @Value("${license.licensePath}") private String licensePath; @Value("${license.publicKeysStorePath}") private String publicStorePath; @Value("${license.subject}") private String subject; @Value("{license.publicAlias}") private String publicAlias; @Value("{license.storePass}") private String storePass; @Component public class LicenseCheckListener implements ApplicationListener { @Override public void onApplicationEvent(ContextRefreshedEvent event) { if (enabled) { logger.info("Installing license on application refresh..."); LicenseVerifyParam param = new LicenseVerifyParam() .setSubject(subject) .setPublicAlias(publicAlias) .setStorePass(storePass) .setLicensePath(licensePath) .setPublicKeysStorePath(publicStorePath); if (param.getLicensePath() != null) { LicenseVerify licenseVerify = new LicenseVerify(); LicenseContent content = licenseVerify.install(param); logger.info("License successfully installed. Valid until: {}, expires at: {}", content.getNotBefore(), content.getNotAfter()); } } } }}
10. 集成许可证拦截器
创建LicenseCheckInterceptor
,在每次请求时校验许可证:
@EnableWebMvcpublic class LicenseInterceptor extends HandlerInterceptorAdapter { @Autowired LicenseVerify licenseVerify; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { logger.entry(); LicenseVerify verify = new LicenseVerify(); if (!verify.verify()) { response.sendRedirect("/login"); return false; } return true; }}
11. 配置Redis缓存(可选)
为了提升性能,可以将许可证校验结果存储在Redis中:
@Configurationpublic class LicenseConfig { @Value("${license.redis.isEnabled}") private boolean enableRedis; @Condition(!enableRedis) public LicenseVerify664ependencies() { return newisque } @Condition(EnableRedis.class) public LicenseRedisConfig config() { return new LicenseRedisConfig(); }}public class LicenseRedisConfig { @Autowired LicenseVerify licenseVerify; @Autowired CacheConfig cacheConfig; @Bean public CacheEvictionHandler handleCacheEvictions() { return new CacheEvictionHandler(); }}
12. 提示验证
在登录页面添加判断逻辑,提示无效的许可证:
Login Login
13. 使用命令生成密钥库
使用keytool生成密钥库:
keytool -genkeypair -keysize 1024 -validity 365 -alias "privateKey" -keystore privateKeys.keystore -storepass "public_password1234" -keypass "private_password1234" -dname "CN=localhost, OU=MyApplication, O=MyCompany, L=Location, ST=State, C=Country"keytool -exportcert -alias "privateKey" -keystore privateKeys.keystore -storepass "public_password1234" -file cert.pemkeytool -import -alias "publicCert" -file cert.pem -keystore publicCerts.keystore -storepass "public_password1234"
14. 部署项目并测试
将War文件部署到应用服务器中,并访问登录页面进行测试,确保每次登录都自动校验许可证。
15. 权力平衡
确保所有OTC相关的日志都被正确记录,并且能方便地定位问题。
16. 上线与维护
部署完成后,持续监控许可证的有效期和硬件信息变化,确保许可证能够及时更新和管理。
通过以上步骤,可以实现以TrueLicense为基础,生成并验证服务器许可证的过程,确保客户端的合法性和项目的安全性。
发表评论
最新留言
很好
[***.229.124.182]2025年04月30日 01时13分46秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
Matlab中save与load函数的使用
2025-04-12
matlab中函数fscanf
2025-04-12
matlab中如何进行优化问题求解-ChatGPT4o作答
2025-04-12
matlab中怎么样算距离,MATLAB 距离计算
2025-04-12
Matlab中数组下标是logical,如何处理?
2025-04-12
matlab中添加文件路径-ChatGPT4o作答
2025-04-12
matlab中的clear函数-ChatGPT4o作答
2025-04-12
Matlab中的LSTM-ChatGPT4o作答
2025-04-12
matlab中的readtable函数详解-ChatGPT4o作答
2025-04-12
matlab中的table数据结构详解-ChatGPT4o作答
2025-04-12
MATLAB中的代码分析器(Code Analyzer)详解-ChatGPT4o作答
2025-04-12
MATLAB中的集合运算
2025-04-12
matlab函数及其功用
2025-04-12
matlab利用guide编写简单计算器界面
2025-04-12
MATLAB利用不同方法实现潜在蒸散发计算
2025-04-12
MATLAB利用小波分析提取周期
2025-04-12
matlab功率谱_EEG信号alpha波beta波等的谱密度实现(1)-原理
2025-04-12