LicenseUtils.java
import de.schlichtherle.license.*;
import javax.security.auth.x500.X500Principal;
import java.io.*;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.prefs.Preferences;
public class LicenseUtils {
private final static X500Principal DEFAULT_HOLDER_AND_ISSUER = new X500Principal("CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN");
/**
*
* @param password 如 hsgfdshf6523424vhdsshdf76324632v4gv23h4526345624
* @param name 如:xxx
* @param keytoolOutputFolder 如:E:\keytool_output\test9
* @param licenseOutputFolder 如:E:\license\xxx\test1
* @param expiryTime 过期时间,格式:'yyyy-MM-dd HH:mm:ss'
*/
public static void generateLicense( String password,
String name,
String keytoolOutputFolder,
String licenseOutputFolder,
String expiryTime ) throws IOException, InterruptedException, ParseException {
File file = new File(keytoolOutputFolder);
if( !file.exists() ){
file.mkdirs();
}
file = new File( licenseOutputFolder );
if( !file.exists() ){
file.mkdirs();
}
String keyPassword = password;
String storePassword = password;
String subjectName = name + "_license";
String privateAlias = name + ".privateKey";
String privateKeyFilePath = keytoolOutputFolder + "/" + name + ".privateKeys.keystore";
String certFilePath = keytoolOutputFolder + "/" + name + ".certfile.cer";
String licenseFilePath = licenseOutputFolder + "/" + name + ".license.lic";
String publicCertsFilePath = keytoolOutputFolder + "/" + name + ".publicCerts.keystore";
String publicCertAlias = name + ".publicCert";
String command1 = "keytool -genkeypair " +
// "-keyalg RSA " +
"-keysize 1024 " +
"-validity 36500 " +
"-alias \"" + privateAlias + "\" " +
"-keystore \"" + privateKeyFilePath + "\" " +
"-storepass \"" + storePassword + "\" " +
"-keypass \"" + keyPassword + "\" " +
"-storetype pkcs12 " +
"-dname \"CN=localhost, OU=localhost, O=localhost, L=SH, ST=SH, C=CN\"";
String command2 = "keytool -exportcert " +
"-alias \"" + privateAlias + "\" " +
"-keystore \"" + privateKeyFilePath + "\" " +
"-storepass \"" + storePassword + "\" " +
"-file \"" + certFilePath + "\"";
String command3 = "echo y | keytool -import " +
"-alias \"" + publicCertAlias + "\" " +
"-file \"" + certFilePath + "\" " +
"-keystore \"" + publicCertsFilePath + "\" " +
"-storepass \"" + storePassword + "\"";
System.out.println(command1 );
System.out.println();
System.out.println(command2 );
System.out.println();
System.out.println(command3 );
System.out.println();
// 生成3个 bat文件
boolean test = true;
if( test ){
File bat1 = new File(keytoolOutputFolder + "/bat1.bat");
BufferedWriter writer1 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(bat1, false)));
writer1.write( command1 );
writer1.write( "\r\n" );
writer1.close();
File bat2 = new File(keytoolOutputFolder + "/bat2.bat");
BufferedWriter writer2 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(bat2, false)));
writer2.write( command2 );
writer2.write( "\r\n" );
writer2.close();
File bat3 = new File(keytoolOutputFolder + "/bat3.bat");
BufferedWriter writer3 = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(bat3, false)));
writer3.write( command3 );
writer3.write( "\r\n" );
writer3.close();
Process process = Runtime.getRuntime().exec("cmd /c cd " + keytoolOutputFolder + " && bat1.bat");
int code = process.waitFor();
System.out.println( "第1步code = " + code );
process = Runtime.getRuntime().exec("cmd /c cd " + keytoolOutputFolder + " && bat2.bat");
code = process.waitFor();
System.out.println( "第2步code = " + code );
process = Runtime.getRuntime().exec("cmd /c cd " + keytoolOutputFolder + " && bat3.bat");
code = process.waitFor();
System.out.println( "第3步code = " + code );
// 删除3个bat文件
bat1.delete();
bat2.delete();
bat3.delete();
}else {
return;
}
// 证书过期时间
Date setExpiryTime = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse( expiryTime );
LicenseCheckModel licenseCheckModel = new LicenseCheckModel();
List<String> macList = new ArrayList<>();
macList.add("xx-xx-xxx-xx-xx");
licenseCheckModel.setMacAddress(macList);
boolean generate = LicenseUtils.generateLicense1(subjectName,
privateAlias,
keyPassword,
storePassword,
licenseFilePath,
privateKeyFilePath,
new Date(),
setExpiryTime,
licenseCheckModel);
System.out.println( "ps:证书生成至 " + licenseFilePath );
}
private static String exec( String command ){
System.out.println( "执行命令:" + command );
BufferedReader reader = null;
try {
Process process = Runtime.getRuntime().exec(command);
// int exitCode = process.waitFor();
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
// reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
String line;
StringBuilder sb = new StringBuilder("");
while ((line = reader.readLine()) != null) {
sb.append( line );
}
String result = sb.toString();
System.out.println( "结果:" + result );
return result;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
if( reader != null ){
try {
reader.close();
}catch ( Exception e ){
e.printStackTrace();
}
}
}
}
/**
* 打印服务器信息
*/
public static void printServerInfo(){
OSUtils.printServerInfo();
}
/**
* 生成License证书
* @return boolean
*/
public static boolean generateLicense1( String subject,
String privateAlias,
String keyPass,
String storePass,
String licensePath,
String privateKeysStorePath,
Date issuedTime,
Date expiryTime,
LicenseCheckModel licenseCheckModel ) {
try {
LicenseParam licenseParam = LicenseUtils.initLicenseParam( storePass,privateKeysStorePath,privateAlias,keyPass,subject );
LicenseManager licenseManager = new CustomLicenseManager( licenseParam );
LicenseContent licenseContent = LicenseUtils.initLicenseContent( subject,
issuedTime,
expiryTime,
licenseCheckModel );
licenseManager.store(licenseContent, new File( licensePath ) );
System.out.println("证书生成成功!");
return true;
} catch (Exception e) {
e.printStackTrace();
System.err.println( "证书生成失败" );
return false;
}
}
/**
* 初始化证书生成参数
*/
private static LicenseParam initLicenseParam( String storePass,
String privateKeysStorePath,
String privateAlias,
String keyPass,
String subject ) {
Preferences preferences = Preferences.userNodeForPackage(LicenseCreator.class);
//设置对证书内容加密的秘钥
CipherParam cipherParam = new DefaultCipherParam( storePass );
KeyStoreParam privateStoreParam = new CustomKeyStoreParam( LicenseCreator.class,
privateKeysStorePath,
privateAlias,
storePass,
keyPass );
LicenseParam licenseParam = new DefaultLicenseParam( subject,preferences,privateStoreParam,cipherParam );
return licenseParam;
}
/**
* 设置证书生成正文信息
*/
private static LicenseContent initLicenseContent( String subject,
Date issuedTime,
Date expiryTime,
LicenseCheckModel licenseCheckModel ) {
LicenseContent licenseContent = new LicenseContent();
licenseContent.setHolder(DEFAULT_HOLDER_AND_ISSUER);
licenseContent.setIssuer(DEFAULT_HOLDER_AND_ISSUER);
licenseContent.setSubject( subject );
licenseContent.setIssued( issuedTime );
licenseContent.setNotBefore( issuedTime );
licenseContent.setNotAfter( expiryTime );
licenseContent.setConsumerType( "user" );
licenseContent.setConsumerAmount( 1 );
licenseContent.setInfo( "" );
//扩展校验服务器硬件信息
licenseContent.setExtra( licenseCheckModel );
return licenseContent;
}
public static void main(String[] args) throws Exception {
LicenseUtils.generateLicense( "123456",
"xxx",
"E:/keytool_output/test11",
"E:/keytool_output/test11/license",
"2033-01-01 00:00:00" );
}
}
OSUtils.java
import com.alibaba.fastjson.JSONObject;
public class OSUtils {
/**
* 打印服务器信息( MAC 信息 )
*/
public static void printServerInfo(){
String osName = System.getProperty("os.name").toLowerCase();
OSInfo serverInfo;
//根据不同操作系统类型选择不同的数据获取方法
if (osName.startsWith("windows")) {
serverInfo = new WindowsOSInfo();
} else if (osName.startsWith("linux")) {
serverInfo = new LinuxOSInfo();
}else{//其他服务器类型
serverInfo = new LinuxOSInfo();
}
System.out.println( "服务器真实信息:" + JSONObject.toJSONString( serverInfo ) );
}
}
CustomLicenseManager.java
import com.alibaba.fastjson.JSONObject;
import de.schlichtherle.license.*;
import de.schlichtherle.xml.GenericCertificate;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.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;
@NoArgsConstructor
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);
}
/**
* 复写create方法
*
* @param
* @return byte[]
*/
@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);
}
/**
* 复写install方法,其中validate方法调用本类中的validate方法,校验IP地址、Mac地址等其他信息
*
* @param
* @return de.schlichtherle.license.LicenseContent
*/
@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;
}
/**
* 复写verify方法,调用本类中的validate方法,校验IP地址、Mac地址等其他信息
*
* @param
* @return de.schlichtherle.license.LicenseContent
*/
@Override
protected synchronized LicenseContent verify(final LicenseNotary notary)
throws Exception {
GenericCertificate certificate = getCertificate();
// 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;
}
/**
* 校验生成证书的参数信息
*
* @param content 证书正文
*/
protected synchronized void validateCreate(final LicenseContent content)
throws LicenseContentException {
final LicenseParam param = getLicenseParam();
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("用户类型不能为空");
}
}
/**
* 复写validate方法,增加IP地址、Mac地址等其他信息校验
*
* @param content LicenseContent
*/
@Override
protected synchronized void validate(final LicenseContent content)
throws LicenseContentException {
//1. 首先调用父类的validate方法
super.validate(content);
//2. 然后校验自定义的License参数
//License中可被允许的参数信息
// todo 为啥为空
LicenseCheckModel expectedCheckModel = (LicenseCheckModel) content.getExtra();
System.out.println("期望服务器信息:" + JSONObject.toJSONString( expectedCheckModel ));
OSUtils.printServerInfo();
//当前服务器真实的参数信息
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 {
// todo win10上报错???
throw new LicenseContentException("不能获取服务器硬件信息");
}
}
/**
* 重写XMLDecoder解析XML
*
* @param encoded XML类型字符串
* @return java.lang.Object
*/
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) {
e.printStackTrace();
// logger.error("XMLDecoder解析XML失败",e);
}
}
return null;
}
/**
* 获取当前服务器需要额外校验的License参数
*
* @return demo.LicenseCheckModel
*/
private LicenseCheckModel getServerInfos() {
//操作系统类型
String osName = System.getProperty("os.name").toLowerCase();
OSInfo osInfo = null;
//根据不同操作系统类型选择不同的数据获取方法
if (osName.startsWith("windows")) {
osInfo = new WindowsOSInfo();
} else if (osName.startsWith("linux")) {
osInfo = new LinuxOSInfo();
} else {//其他服务器类型
osInfo = new LinuxOSInfo();
}
return LicenseCheckModel.build(osInfo);
}
/**
* 校验当前服务器的IP/Mac地址是否在可被允许的IP范围内<br/>
* 如果存在IP在可被允许的IP/Mac地址范围内,则返回true
*
* @return boolean
*/
private boolean checkIpAddress(List<String> expectedList, List<String> serverList) {
if (expectedList != null && expectedList.size() > 0) {
if (serverList != null && serverList.size() > 0) {
for (String expected : expectedList) {
if (serverList.contains(expected.trim())) {
return true;
}
}
}
return false;
} else {
return true;
}
}
/**
* 校验当前服务器硬件(主板、CPU等)序列号是否在可允许范围内
*
* @return boolean
*/
private boolean checkSerial(String expectedSerial, String serverSerial) {
if (StringUtils.isNotBlank(expectedSerial)) {
if (StringUtils.isNotBlank(serverSerial)) {
if (expectedSerial.equals(serverSerial)) {
return true;
}
}
return false;
} else {
return true;
}
}
}
LinuxOSInfo
import java.net.InetAddress;
import java.util.List;
import java.util.stream.Collectors;
public class LinuxOSInfo extends OSInfo {
/*@Override
public List<String> getIpAddress() throws Exception {
List<String> result = null;
//获取所有网络接口
List<InetAddress> inetAddresses = getLocalAllInetAddress();
if (inetAddresses != null && inetAddresses.size() > 0) {
result = inetAddresses.stream().map(InetAddress::getHostAddress).distinct().map(String::toLowerCase).collect(Collectors.toList());
}
return result;
}*/
@Override
public List<String> getMacAddress() throws Exception {
List<String> result = null;
//1. 获取所有网络接口
List<InetAddress> inetAddresses = getLocalAllInetAddress();
if (inetAddresses != null && inetAddresses.size() > 0) {
//2. 获取所有网络接口的Mac地址
result = inetAddresses.stream().map(this::getMacByInetAddress).distinct().collect(Collectors.toList());
}
return result;
}
/* @Override
public 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.isNotBlank(line)) {
serialNumber = line;
}
reader.close();
return serialNumber;
}*/
/*@Override
public 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.isNotBlank(line)) {
serialNumber = line;
}
reader.close();
return serialNumber;
}*/
}
OSInfo.java
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
public abstract class OSInfo {
/**
* 获取IP地址
*/
// todo public abstract List<String> getIpAddress() throws Exception;
/**
* 获取Mac地址
*/
public abstract List<String> getMacAddress() throws Exception;
/**
* 获取CPU序列号
*/
// todo public abstract String getCPUSerial() throws Exception;
/**
* 获取主板序列号
*/
// todo public abstract String getMainBoardSerial() throws Exception;
/**
* 获取当前服务器所有符合条件的InetAddress
*/
protected List<InetAddress> getLocalAllInetAddress() throws Exception {
List<InetAddress> result = new ArrayList<>(4);
// 遍历所有的网络接口
for (Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); networkInterfaces.hasMoreElements(); ) {
NetworkInterface iface = (NetworkInterface) networkInterfaces.nextElement();
// 在所有的接口下再遍历IP
for (Enumeration inetAddresses = iface.getInetAddresses(); inetAddresses.hasMoreElements(); ) {
InetAddress inetAddr = (InetAddress) inetAddresses.nextElement();
//排除LoopbackAddress、SiteLocalAddress、LinkLocalAddress、MulticastAddress类型的IP地址
if (!inetAddr.isLoopbackAddress() /*&& !inetAddr.isSiteLocalAddress()*/
&& !inetAddr.isLinkLocalAddress() && !inetAddr.isMulticastAddress()) {
result.add(inetAddr);
}
}
}
return result;
}
/**
* 获取某个网络接口的Mac地址
*/
protected String getMacByInetAddress(InetAddress inetAddr) {
try {
byte[] mac = NetworkInterface.getByInetAddress(inetAddr).getHardwareAddress();
StringBuffer stringBuffer = new StringBuffer();
for (int i = 0; i < mac.length; i++) {
if (i != 0) {
stringBuffer.append("-");
}
//将十六进制byte转化为字符串
String temp = Integer.toHexString(mac[i] & 0xff);
if (temp.length() == 1) {
stringBuffer.append("0" + temp);
} else {
stringBuffer.append(temp);
}
}
return stringBuffer.toString().toUpperCase();
} catch (SocketException e) {
e.printStackTrace();
}
return null;
}
}
WindowsOSInfo.java
import java.net.InetAddress;
import java.util.List;
import java.util.stream.Collectors;
public class WindowsOSInfo extends OSInfo {
/*@Override
public List<String> getIpAddress() throws Exception {
List<String> result = null;
//获取所有网络接口
List<InetAddress> inetAddresses = getLocalAllInetAddress();
if (inetAddresses != null && inetAddresses.size() > 0) {
result = inetAddresses.stream().map(InetAddress::getHostAddress).distinct().map(String::toLowerCase).collect(Collectors.toList());
}
return result;
}*/
@Override
public List<String> getMacAddress() throws Exception {
List<String> result = null;
//1. 获取所有网络接口
List<InetAddress> inetAddresses = getLocalAllInetAddress();
if (inetAddresses != null && inetAddresses.size() > 0) {
//2. 获取所有网络接口的Mac地址
result = inetAddresses.stream().map(this::getMacByInetAddress).distinct().collect(Collectors.toList());
}
return result;
}
/*@Override
public 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;
}*/
/* @Override
public 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;
}*/
}
CustomKeyStoreParam.java
import de.schlichtherle.license.AbstractKeyStoreParam;
import lombok.Getter;
import lombok.Setter;
import java.io.*;
/**
* @desc 自定义KeyStoreParam,用于将公私钥存储文件存放到其他磁盘位置而不是项目中
*/
@Getter
@Setter
public class CustomKeyStoreParam extends AbstractKeyStoreParam {
//公钥/私钥在磁盘上的存储路径
private String storePath;
//访问秘钥库的密码
private String storePwd;
//别称
private String alias;
//密钥密码(需要妥善保管,不能让使用者知道)
private 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;
}
/**
* 用于将公私钥存储文件存放到其他磁盘位置而不是项目中
* @return
* @throws IOException
*/
@Override
public InputStream getStream() throws IOException {
final InputStream in = new FileInputStream(new File(storePath));
if (null == in){
throw new FileNotFoundException(storePath);
}
return in;
}
}
LicenseCheckModel.java
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.extern.slf4j.Slf4j;
import java.io.Serializable;
import java.util.List;
/**
* @desc 自定义需要校验的License参数
*/
@Setter
@Getter
@ToString
@Slf4j
public class LicenseCheckModel implements Serializable {
/**
* 可被允许的IP地址
*/
// private List<String> ipAddress;
/**
* 可被允许的MAC地址
*/
private List<String> macAddress;
/**
* 可被允许的CPU序列号
*/
// private String cpuSerial;
/**
* 可被允许的主板序列号
*/
// private String mainBoardSerial;
public static LicenseCheckModel build(OSInfo serverInfo){
LicenseCheckModel result = new LicenseCheckModel();
try {
// result.setIpAddress(serverInfo.getIpAddress());
result.setMacAddress(serverInfo.getMacAddress());
// result.setCpuSerial(serverInfo.getCPUSerial());
// result.setMainBoardSerial(serverInfo.getMainBoardSerial());
}catch (Exception e){
log.error("获取服务器硬件信息失败",e);
}
return result;
}
}
LicenseInterceptor.java
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
/**
* @desc 证书校验拦截器
*/
@Component
public class LicenseInterceptor implements HandlerInterceptor {
@Autowired
private RedisTemplate<String,Object> redisTemplate;
@Value( "${spring.profiles.active}" )
private String profiles;
@Autowired
private ILicenseService licenseService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object obj) throws Exception {
Boolean valid = this.licenseService.checkLicenseValid();
if( valid ){
return true;
}else{
// 证书校验失败
response.setCharacterEncoding("utf-8");
response.setHeader("Content-Type", "text/html;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
Result<Object> result = ResultBuilder.error("您的证书无效,请核查服务器是否取得授权或重新申请证书!");
PrintWriter writer = response.getWriter();
writer.print( JSONObject.toJSONString( result ) );
writer.close();
return false;
}
}
@Override
public void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object obj, Exception err) throws Exception {
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,Object obj, ModelAndView mav) throws Exception {
}
}
pom.xml
<!-- License -->
<dependency>
<groupId>de.schlichtherle.truelicense</groupId>
<artifactId>truelicense-core</artifactId>
<version>1.33</version>
</dependency>
bootstrap.yml
license:
enable: true
subject: xxx_license #证书主题
publicAlias: xxx.publicCert #公钥别称
storePass: 123456 #访问公钥库的密码
licensePath: E:/keytool_output/test11/license/xxx.license.lic #授权文件所在目录
publicKeysStorePath: E:/keytool_output/test11/xxx.publicCerts.keystore #公钥库存储路径