项目名称: true-license-demo
*文件名称: AbstractServerInfos.java
*方法描述: 组装需要额外校验的License参数
*创建时间: 2020/10/10 11:01
* * @return LicenseCheckModel * @author 方瑞冬 * @version 1.0 */ public LicenseCheckModel getServerInfos() { LicenseCheckModel result = new LicenseCheckModel(); try { result.setIpAddress(this.getIpAddress()); result.setMacAddress(this.getMacAddress()); result.setCpuSerial(this.getCPUSerial()); result.setMainBoardSerial(this.getMainBoardSerial()); } catch (Exception e) { log.error("获取服务器硬件信息失败", e); } return result; } /** *项目名称: true-license-demo
*文件名称: AbstractServerInfos.java
*方法描述: 获取 IP 地址
*创建时间: 2020/10/10 11:02
* * @return java.util.List项目名称: true-license-demo
*文件名称: AbstractServerInfos.java
*方法描述: 获取 Mac 地址
*创建时间: 2020/10/10 11:02
* * @return java.util.List项目名称: true-license-demo
*文件名称: AbstractServerInfos.java
*方法描述: 获取 CPU 序列号
*创建时间: 2020/10/10 11:02
* * @return java.lang.String * @author 方瑞冬 * @version 1.0 */ protected abstract String getCPUSerial() throws Exception; /** *项目名称: true-license-demo
*文件名称: AbstractServerInfos.java
*方法描述: 获取主板序列号
*创建时间: 2020/10/10 11:02
* * @return java.lang.String * @author 方瑞冬 * @version 1.0 */ protected abstract String getMainBoardSerial() throws Exception; /** *项目名称: true-license-demo
*文件名称: AbstractServerInfos.java
*方法描述: 获取当前服务器所有符合条件的 InetAddress
*创建时间: 2020/10/10 11:02
* * @return java.util.List项目名称: true-license-demo
*文件名称: AbstractServerInfos.java
*方法描述: 获取某个网络接口的 Mac 地址
*创建时间: 2020/10/10 11:03
* * @param inetAddr inetAddr * @return java.lang.String * @author 方瑞冬 * @version 1.0 */ protected String getMacByInetAddress(InetAddress inetAddr) { try { byte[] mac = NetworkInterface.getByInetAddress(inetAddr).getHardwareAddress(); StringBuilder stringBuilder = new StringBuilder(); for (int i = 0; i < mac.length; i++) { if (i != 0) { stringBuilder.append("-"); } //将十六进制 byte 转化为字符串 String temp = Integer.toHexString(mac[i] & 0xff); if (temp.length() == 1) { stringBuilder.append("0").append(temp); } else { stringBuilder.append(temp); } } return stringBuilder.toString().toUpperCase(); } catch (SocketException e) { e.printStackTrace(); } return null; } } ``` ## 获取客户 Linux 服务器的基本信息 ``` /** * Project Name: true-license * File Name: LinuxServerInfos * Package Name: com.example.demo.entity * Date: 2020/10/10 11:05 * Author: 方瑞冬 */ package com.example.demo.license; import org.springframework.util.StringUtils; import java.io.BufferedReader; import java.io.InputStreamReader; import java.net.InetAddress; import java.util.List; import java.util.stream.Collectors; /** * @author 方瑞冬 * 获取客户 Linux 服务器的基本信息 */ public class LinuxServerInfos extends AbstractServerInfos { /** *项目名称: true-license-demo
*文件名称: LinuxServerInfos.java
*方法描述: 获取 IP 地址
*创建时间: 2020/10/10 11:07
* * @return java.util.List项目名称: true-license-demo
*文件名称: LinuxServerInfos.java
*方法描述: 获取 Mac 地址
*创建时间: 2020/10/10 11:08
* * @return java.util.List项目名称: true-license-demo
*文件名称: LinuxServerInfos.java
*方法描述: 获取 CPU 序列号
*创建时间: 2020/10/10 11:08
* * @return java.lang.String * @author 方瑞冬 * @version 1.0 */ @Override protected String getCPUSerial() throws Exception { //序列号 String serialNumber = ""; //使用 dmidecode 命令获取 CPU 序列号 String[] shell = {"/bin/bash", "-c", "dmidecode -t processor | grep 'ID' | awk -F ':' '{print $2}' | head -n 1"}; Process process = Runtime.getRuntime().exec(shell); process.getOutputStream().close(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = reader.readLine().trim(); if (StringUtils.hasText(line)) { serialNumber = line; } reader.close(); return serialNumber; } /** *项目名称: true-license-demo
*文件名称: LinuxServerInfos.java
*方法描述: 获取主板序列号
*创建时间: 2020/10/10 11:08
* * @return java.lang.String * @author 方瑞冬 * @version 1.0 */ @Override protected String getMainBoardSerial() throws Exception { //序列号 String serialNumber = ""; //使用 dmidecode 命令获取主板序列号 String[] shell = {"/bin/bash", "-c", "dmidecode | grep 'Serial Number' | awk -F ':' '{print $2}' | head -n 1"}; Process process = Runtime.getRuntime().exec(shell); process.getOutputStream().close(); BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); String line = reader.readLine().trim(); if (StringUtils.hasText(line)) { serialNumber = line; } reader.close(); return serialNumber; } } ``` ## 获取客户 Windows 服务器的基本信息 ``` /** * Project Name: true-license * File Name: WindowsServerInfos * Package Name: com.example.demo.entity * Date: 2020/10/10 11:14 * Author: 方瑞冬 */ package com.example.demo.license; import java.net.InetAddress; import java.util.List; import java.util.Scanner; import java.util.stream.Collectors; /** * @author 方瑞冬 * 获取客户 Windows 服务器的基本信息 */ public class WindowsServerInfos extends AbstractServerInfos { /** *项目名称: true-license-demo
*文件名称: WindowsServerInfos.java
*方法描述: 获取 IP 地址
*创建时间: 2020/10/10 11:22
* * @return java.util.List项目名称: true-license-demo
*文件名称: WindowsServerInfos.java
*方法描述: 获取 Mac 地址
*创建时间: 2020/10/10 11:23
* * @return java.util.List项目名称: true-license-demo
*文件名称: WindowsServerInfos.java
*方法描述: 获取 CPU 序列号
*创建时间: 2020/10/10 11:23
* * @return java.lang.String * @author 方瑞冬 * @version 1.0 */ @Override protected String getCPUSerial() throws Exception { //序列号 String serialNumber = ""; //使用 WMIC 获取 CPU 序列号 Process process = Runtime.getRuntime().exec("wmic cpu get processorid"); process.getOutputStream().close(); Scanner scanner = new Scanner(process.getInputStream()); if (scanner.hasNext()) { scanner.next(); } if (scanner.hasNext()) { serialNumber = scanner.next().trim(); } scanner.close(); return serialNumber; } /** *项目名称: true-license-demo
*文件名称: WindowsServerInfos.java
*方法描述: 获取主板序列号
*创建时间: 2020/10/10 11:23
* * @return java.lang.String * @author 方瑞冬 * @version 1.0 */ @Override protected String getMainBoardSerial() throws Exception { //序列号 String serialNumber = ""; //使用 WMIC 获取主板序列号 Process process = Runtime.getRuntime().exec("wmic baseboard get serialnumber"); process.getOutputStream().close(); Scanner scanner = new Scanner(process.getInputStream()); if (scanner.hasNext()) { scanner.next(); } if (scanner.hasNext()) { serialNumber = scanner.next().trim(); } scanner.close(); return serialNumber; } } ``` ## 自定义 License 管理,创建、安装、校验等 ``` /** * Project Name: true-license * File Name: CustomLicenseManager * Package Name: com.example.demo.entity * Date: 2020/10/10 13:02 * Author: 方瑞冬 */ package com.example.demo.license; import de.schlichtherle.license.*; import de.schlichtherle.xml.GenericCertificate; import lombok.extern.slf4j.Slf4j; import org.springframework.util.StringUtils; import java.beans.XMLDecoder; import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.UnsupportedEncodingException; import java.util.Date; import java.util.List; /** * @author 方瑞冬 * 自定义 License 管理,创建、安装、校验等 */ @Slf4j public class CustomLicenseManager extends LicenseManager { /** * XML 编码 */ private static final String XML_CHARSET = "UTF-8"; /** * 默认 BUFSIZE */ private static final int DEFAULT_BUFSIZE = 8 * 1024; public CustomLicenseManager(LicenseParam param) { super(param); } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 重写 License 创建
*创建时间: 2020/10/10 13:11
* * @param content LicenseContent * @param notary LicenseNotary * @return byte[] * @author 方瑞冬 * @version 1.0 */ @Override protected synchronized byte[] create(LicenseContent content, LicenseNotary notary) throws Exception { initialize(content); this.validateCreate(content); final GenericCertificate certificate = notary.sign(content); return getPrivacyGuard().cert2key(certificate); } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 重写 License 安装
*创建时间: 2020/10/10 13:13
* * @param key key * @param notary LicenseNotary * @return de.schlichtherle.license.LicenseContent * @author 方瑞冬 * @version 1.0 */ @Override protected synchronized LicenseContent install(final byte[] key, final LicenseNotary notary) throws Exception { final GenericCertificate certificate = getPrivacyGuard().key2cert(key); notary.verify(certificate); final LicenseContent content = (LicenseContent) this.load(certificate.getEncoded()); this.validate(content); setLicenseKey(key); setCertificate(certificate); return content; } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 重写 License 校验
*创建时间: 2020/10/10 13:14
* * @param notary LicenseNotary * @return de.schlichtherle.license.LicenseContent * @author 方瑞冬 * @version 1.0 */ @Override protected synchronized LicenseContent verify(final LicenseNotary notary) throws Exception { GenericCertificate certificate; // Load license key from preferences, final byte[] key = getLicenseKey(); if (null == key) { throw new NoLicenseInstalledException(getLicenseParam().getSubject()); } certificate = getPrivacyGuard().key2cert(key); notary.verify(certificate); final LicenseContent content = (LicenseContent) this.load(certificate.getEncoded()); this.validate(content); setCertificate(certificate); return content; } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 校验生成证书的参数信息
*创建时间: 2020/10/10 13:14
* * @param content LicenseContent * @return void * @author 方瑞冬 * @version 1.0 */ protected synchronized void validateCreate(final LicenseContent content) throws LicenseContentException { final Date now = new Date(); final Date notBefore = content.getNotBefore(); final Date notAfter = content.getNotAfter(); if (null != notAfter && now.after(notAfter)) { throw new LicenseContentException("证书失效时间不能早于当前时间"); } if (null != notBefore && null != notAfter && notAfter.before(notBefore)) { throw new LicenseContentException("证书生效时间不能晚于证书失效时间"); } final String consumerType = content.getConsumerType(); if (null == consumerType) { throw new LicenseContentException("用户类型不能为空"); } } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 重写 License 验证
*创建时间: 2020/10/10 13:15
* * @param content LicenseContent * @return void * @author 方瑞冬 * @version 1.0 */ @Override protected synchronized void validate(final LicenseContent content) throws LicenseContentException { //1. 首先调用父类的validate方法 super.validate(content); //2. 然后校验自定义的License参数 //License中可被允许的参数信息 LicenseCheckModel expectedCheckModel = (LicenseCheckModel) content.getExtra(); //当前服务器真实的参数信息 LicenseCheckModel serverCheckModel = getServerInfos(); if (expectedCheckModel != null && serverCheckModel != null) { //校验IP地址 if (!checkIpAddress(expectedCheckModel.getIpAddress(), serverCheckModel.getIpAddress())) { throw new LicenseContentException("当前服务器的IP没在授权范围内"); } //校验Mac地址 if (!checkIpAddress(expectedCheckModel.getMacAddress(), serverCheckModel.getMacAddress())) { throw new LicenseContentException("当前服务器的Mac地址没在授权范围内"); } //校验主板序列号 if (!checkSerial(expectedCheckModel.getMainBoardSerial(), serverCheckModel.getMainBoardSerial())) { throw new LicenseContentException("当前服务器的主板序列号没在授权范围内"); } //校验CPU序列号 if (!checkSerial(expectedCheckModel.getCpuSerial(), serverCheckModel.getCpuSerial())) { throw new LicenseContentException("当前服务器的CPU序列号没在授权范围内"); } } else { throw new LicenseContentException("不能获取服务器硬件信息"); } } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: XMLDecoder 解析 XML
*创建时间: 2020/10/10 13:16
* * @param encoded encoded * @return java.lang.Object * @author 方瑞冬 * @version 1.0 */ private Object load(String encoded) { BufferedInputStream inputStream = null; XMLDecoder decoder = null; try { inputStream = new BufferedInputStream(new ByteArrayInputStream(encoded.getBytes(XML_CHARSET))); decoder = new XMLDecoder(new BufferedInputStream(inputStream, DEFAULT_BUFSIZE), null, null); return decoder.readObject(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } finally { try { if (decoder != null) { decoder.close(); } if (inputStream != null) { inputStream.close(); } } catch (Exception e) { log.error("XMLDecoder解析XML失败", e); } } return null; } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 获取当前服务器需要额外校验的 License 参数
*创建时间: 2020/10/10 13:16
* * @return com.example.demo.license.LicenseCheckModel * @author 方瑞冬 * @version 1.0 */ private LicenseCheckModel getServerInfos() { //操作系统类型 String osName = System.getProperty("os.name").toLowerCase(); AbstractServerInfos abstractServerInfos; //根据不同操作系统类型选择不同的数据获取方法 if (osName.startsWith("windows")) { abstractServerInfos = new WindowsServerInfos(); } else if (osName.startsWith("linux")) { abstractServerInfos = new LinuxServerInfos(); } else {//其他服务器类型 abstractServerInfos = new LinuxServerInfos(); } return abstractServerInfos.getServerInfos(); } /** *项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 校验当前服务器的IP/Mac地址是否在可被允许的IP范围内
*创建时间: 2020/10/10 13:17
* * @param expectedList expectedList * @param serverList serverList * @return boolean * @author 方瑞冬 * @version 1.0 */ private boolean checkIpAddress(List项目名称: true-license-demo
*文件名称: CustomLicenseManager.java
*方法描述: 校验当前服务器硬件(主板、CPU 等)序列号是否在可允许范围内
*创建时间: 2020/10/10 13:18
* * @param expectedSerial expectedSerial * @param serverSerial serverSerial * @return boolean * @author 方瑞冬 * @version 1.0 */ private boolean checkSerial(String expectedSerial, String serverSerial) { if (StringUtils.hasText(expectedSerial)) { if (StringUtils.hasText(serverSerial)) { return expectedSerial.equals(serverSerial); } return false; } else { return true; } } } ``` ## 自定义密钥存储 ``` /** * Project Name: true-license * File Name: CustomKeyStoreParam * Package Name: com.example.demo.entity * Date: 2020/10/10 13:30 * Author: 方瑞冬 */ package com.example.demo.license; import de.schlichtherle.license.AbstractKeyStoreParam; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; /** * @author 方瑞冬 * 自定义 KeyStoreParam,用于将公私钥存储文件存放到其他磁盘位置而不是项目中 * 实际使用的时候公钥大部分都不会放在项目中的 */ public class CustomKeyStoreParam extends AbstractKeyStoreParam { /** * 公钥/私钥在磁盘上的存储路径 */ private final String storePath; private final String alias; private final String storePwd; private final String keyPwd; public CustomKeyStoreParam(Class clazz, String resource, String alias, String storePwd, String keyPwd) { super(clazz, resource); this.storePath = resource; this.alias = alias; this.storePwd = storePwd; this.keyPwd = keyPwd; } @Override public String getAlias() { return alias; } @Override public String getStorePwd() { return storePwd; } @Override public String getKeyPwd() { return keyPwd; } /** *项目名称: true-license-demo
*文件名称: CustomKeyStoreParam.java
*方法描述: 用于将公私钥存储文件存放到其他磁盘位置而不是项目中,AbstractKeyStoreParam 里面的 getStream() 方法默认文件是存储的项目中
*创建时间: 2020/10/10 13:31
* * @param * @return java.io.InputStream * @author 方瑞冬 * @version 1.0 */ @Override public InputStream getStream() throws IOException { return new FileInputStream(new File(storePath)); } } ``` ## License 创建 ``` /** * Project Name: true-license * File Name: LicenseCreator * Package Name: com.example.demo.entity * Date: 2020/10/10 13:22 * Author: 方瑞冬 */ package com.example.demo.license; import de.schlichtherle.license.*; import lombok.extern.slf4j.Slf4j; import javax.security.auth.x500.X500Principal; import java.io.File; import java.text.MessageFormat; import java.util.prefs.Preferences; /** * @author 方瑞冬 * License 创建 */ @Slf4j public class LicenseCreator { private final static X500Principal DEFAULT_HOLDER_AND_ISSUER = new X500Principal("CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN"); private final LicenseCreatorParam param; public LicenseCreator(LicenseCreatorParam param) { this.param = param; } /** *项目名称: true-license-demo
*文件名称: LicenseCreator.java
*方法描述: 生成 License 证书
*创建时间: 2020/10/10 13:32
* * @return boolean * @author 方瑞冬 * @version 1.0 */ public boolean generateLicense() { try { LicenseManager licenseManager = new CustomLicenseManager(initLicenseParam()); LicenseContent licenseContent = initLicenseContent(); licenseManager.store(licenseContent, new File(param.getLicensePath())); return true; } catch (Exception e) { log.error(MessageFormat.format("证书生成失败:{0}", param), e); return false; } } /** *项目名称: true-license-demo
*文件名称: LicenseCreator.java
*方法描述: 初始化证书生成参数
*创建时间: 2020/10/10 13:33
* * @return de.schlichtherle.license.LicenseParam * @author 方瑞冬 * @version 1.0 */ private LicenseParam initLicenseParam() { Preferences preferences = Preferences.userNodeForPackage(LicenseCreator.class); //设置对证书内容加密的秘钥 CipherParam cipherParam = new DefaultCipherParam(param.getStorePass()); KeyStoreParam privateStoreParam = new CustomKeyStoreParam(LicenseCreator.class , param.getPrivateKeysStorePath() , param.getPrivateAlias() , param.getStorePass() , param.getKeyPass()); return new DefaultLicenseParam(param.getSubject() , preferences , privateStoreParam , cipherParam); } /** *项目名称: true-license-demo
*文件名称: LicenseCreator.java
*方法描述: 设置证书生成正文信息
*创建时间: 2020/10/10 13:34
* * @return de.schlichtherle.license.LicenseContent * @author 方瑞冬 * @version 1.0 */ private LicenseContent initLicenseContent() { LicenseContent licenseContent = new LicenseContent(); licenseContent.setHolder(DEFAULT_HOLDER_AND_ISSUER); licenseContent.setIssuer(DEFAULT_HOLDER_AND_ISSUER); licenseContent.setSubject(param.getSubject()); licenseContent.setIssued(param.getIssuedTime()); licenseContent.setNotBefore(param.getIssuedTime()); licenseContent.setNotAfter(param.getExpiryTime()); licenseContent.setConsumerType(param.getConsumerType()); licenseContent.setConsumerAmount(param.getConsumerAmount()); licenseContent.setInfo(param.getDescription()); //扩展校验服务器硬件信息 licenseContent.setExtra(param.getLicenseCheckModel()); return licenseContent; } } ``` ## 证书配置 ``` /** * Project Name: true-license * File Name: LicenseConfig * Package Name: com.example.demo.license * Date: 2020/10/10 14:03 * Author: 方瑞冬 */ package com.example.demo.license; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * @author 方瑞冬 * 证书配置 */ @Data @Configuration @ConfigurationProperties("license") @Slf4j public class LicenseConfig { /** * 证书 subject */ private String subject; /** * 公钥别称 */ private String publicAlias; /** * 访问公钥库的密码 */ private String storePass; /** * 证书生成路径 */ private String licensePath; /** * 密钥库存储路径 */ private String publicKeysStorePath; /** *项目名称: true-license-demo
*文件名称: LicenseConfig.java
*方法描述: 把 LicenseVerify 类添加到 Spring 容器。在 LicenseVerify 从 Spring 容器添加或移除的时候调用证书安装或卸载
*创建时间: 2020/10/10 16:07
* * @return com.example.demo.licensegenerate.LicenseVerify * @author 方瑞冬 * @version 1.0 */ @Bean(initMethod = "installLicense", destroyMethod = "unInstallLicense") public LicenseVerify licenseVerify() { return new LicenseVerify(subject, publicAlias, storePass, licensePath, publicKeysStorePath); } } ``` ## License 校验、安装、卸载 ``` /** * Project Name: true-license * File Name: LicenseVerify * Package Name: com.example.demo.licenseverify * Date: 2020/10/10 15:46 * Author: 方瑞冬 */ package com.example.demo.license; import de.schlichtherle.license.*; import lombok.extern.slf4j.Slf4j; import java.io.File; import java.text.DateFormat; import java.text.MessageFormat; import java.text.SimpleDateFormat; import java.util.prefs.Preferences; /** * @author 方瑞冬 * Lincense 校验、安装、卸载 */ @Slf4j public class LicenseVerify { /** * 证书subject */ private final String subject; /** * 公钥别称 */ private final String publicAlias; /** * 访问公钥库的密码 */ private final String storePass; /** * 证书生成路径 */ private final String licensePath; /** * 密钥库存储路径 */ private final String publicKeysStorePath; /** * LicenseManager */ private LicenseManager licenseManager; /** * 证书是否安装成功标记 */ private boolean installSuccess; public LicenseVerify(String subject, String publicAlias, String storePass, String licensePath, String publicKeysStorePath) { this.subject = subject; this.publicAlias = publicAlias; this.storePass = storePass; this.licensePath = licensePath; this.publicKeysStorePath = publicKeysStorePath; } /** *项目名称: true-license-demo
*文件名称: LicenseVerify.java
*方法描述: 安装 License 证书,读取证书相关的信息, 在 Bean 加入容器的时候自动调用
*创建时间: 2020/10/10 15:58
* * @return void * @author 方瑞冬 * @version 1.0 */ public void installLicense() { try { Preferences preferences = Preferences.userNodeForPackage(LicenseVerify.class); CipherParam cipherParam = new DefaultCipherParam(storePass); KeyStoreParam publicStoreParam = new CustomKeyStoreParam(LicenseVerify.class, publicKeysStorePath, publicAlias, storePass, null); LicenseParam licenseParam = new DefaultLicenseParam(subject, preferences, publicStoreParam, cipherParam); licenseManager = new CustomLicenseManager(licenseParam); licenseManager.uninstall(); LicenseContent licenseContent = licenseManager.install(new File(licensePath)); DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); installSuccess = true; log.info("------------------------------- 证书安装成功 -------------------------------"); log.info(MessageFormat.format("证书校验通过,证书有效期:{0} - {1}", format.format(licenseContent.getNotBefore()), format.format(licenseContent.getNotAfter()))); } catch (Exception e) { installSuccess = false; log.error("------------------------------- 证书安装失败 -------------------------------"); log.error(e.getMessage(), e); } } /** *项目名称: true-license-demo
*文件名称: LicenseVerify.java
*方法描述: 卸载证书,在 Bean 从容器移除的时候自动调用
*创建时间: 2020/10/10 15:58
* * @return void * @author 方瑞冬 * @version 1.0 */ public void unInstallLicense() { if (installSuccess) { try { licenseManager.uninstall(); log.info("------------------------------- 证书卸载成功 -------------------------------"); } catch (Exception e) { log.error("------------------------------- 证书卸载失败 -------------------------------"); log.error(e.getMessage(), e); } } } /** *项目名称: true-license-demo
*文件名称: LicenseVerify.java
*方法描述:
*创建时间: 2020/10/10 16:00
* * @return boolean * @author 方瑞冬 * @version 1.0 */ public boolean verify() { try { LicenseContent licenseContent = licenseManager.verify(); DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); log.info(MessageFormat.format("证书有效期:{0} - {1}", format.format(licenseContent.getNotBefore()), format.format(licenseContent.getNotAfter()))); return true; } catch (Exception e) { log.error("证书校验失败" + e.getMessage(), e); return false; } } } ``` ## License 生成证书 Service ### LicenseCreatorService ``` /** * Project Name: true-license * File Name: LicenseCreatorService * Package Name: com.example.demo.service * Date: 2020/10/10 13:44 * Author: 方瑞冬 */ package com.example.demo.service; import com.example.demo.license.LicenseCheckModel; import com.example.demo.license.LicenseCreatorParam; import java.util.Map; /** * @author 方瑞冬 */ public interface LicenseCreatorService { /** *项目名称: true-license-demo
*文件名称: LicenseCreatorService.java
*方法描述: 获取服务器硬件信息
*创建时间: 2020/10/10 13:45
* * @param osName 系统名称 * @return com.example.demo.license.LicenseCheckModel * @author 方瑞冬 * @version 1.0 */ LicenseCheckModel getServerInfos(String osName); /** *项目名称: true-license-demo
*文件名称: LicenseCreatorService.java
*方法描述: 生成证书
*创建时间: 2020/10/10 13:45
* * @param param 证书创建参数 * @return java.util.Map项目名称: true-license-demo
*文件名称: LicenseCreatorServiceImpl.java
*方法描述: 获取服务器硬件信息
*创建时间: 2020/10/10 13:46
* * @param osName 系统名称 * @return com.example.demo.license.LicenseCheckModel * @author 方瑞冬 * @version 1.0 */ @Override public LicenseCheckModel getServerInfos(String osName) { //操作系统类型 if (StringUtils.isEmpty(osName)) { osName = System.getProperty("os.name"); } osName = osName.toLowerCase(); AbstractServerInfos abstractServerInfos = null; //根据不同操作系统类型选择不同的数据获取方法 if (osName.startsWith("windows")) { abstractServerInfos = new WindowsServerInfos(); } else if (osName.startsWith("linux")) { abstractServerInfos = new LinuxServerInfos(); } else {//其他服务器类型 abstractServerInfos = new LinuxServerInfos(); } return abstractServerInfos.getServerInfos(); } /** *项目名称: true-license-demo
*文件名称: LicenseCreatorServiceImpl.java
*方法描述: 生成证书
*创建时间: 2020/10/10 13:46
* * @param param 证书创建参数 * @return java.util.Map项目名称: true-license-demo
*文件名称: LicenseCreatorController.java
*方法描述: 获取服务器硬件信息
*创建时间: 2020/10/10 13:39
* * @param osName 系统名称 * @return com.example.demo.license.LicenseCheckModel * @author 方瑞冬 * @version 1.0 */ @GetMapping("/getServerInfos") public LicenseCheckModel getServerInfos(@RequestParam String osName) { return licenseCreatorService.getServerInfos(osName); } /** *项目名称: true-license-demo
*文件名称: LicenseCreatorController.java
*方法描述: 生成证书
*创建时间: 2020/10/10 13:42
* * @param param 证书创建参数 * @return java.util.Map