由于客户需要对公司销售的软件进行试用,公司考虑只允许客户在指定服务器上进去短期试用,所以在系统中集成了License授权模块。
首先,我们需要获取要部署的服务器的基本信息,然后根据服务器信息生成对应的许可证,许可证采用DSA加密算法进行加密,再通过网关过滤器,对所有权限进行校验。
创建获取服务器基本信息模块,打成jar包,在要授权的机器上运行,生成 device.json 文件
<dependency>
<groupId>net.sourceforge.nekohtml</groupId>
<artifactId>nekohtml</artifactId>
<version>1.9.18</version>
</dependency>
<dependency>
<groupId>de.schlichtherle.truelicense</groupId>
<artifactId>truelicense-core</artifactId>
<version>1.33</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
通过 DeviceUtil 获取对应的设备信息并生成 device.json 文件到 ./license 目录下,可自行定义目录地址。
public class LicenseDeviceApplication {
public static void main(String[] args) {
try {
DeviceInfo deviceInfo = DeviceUtil.getDeviceInfo();
String json = new Gson().toJson(deviceInfo);
Files.createDirectories(Paths.get("license"));
Files.writeString(Paths.get("license", "device.json"), json);
System.out.println("success");
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Data
@Accessors(chain = true)
public class DeviceInfo {
private String cpu;
private String mainBoard;
private List<String> ipList;
private List<String> macList;
}
DeviceUtil 根据不同的操作系统采用不同的方式获取服务器数据
public class DeviceUtil {
private static final String WIN_PRE = "win";
public static DeviceInfo getDeviceInfo() throws Exception {
String os = System.getProperty("os.name").toLowerCase();
Device device;
if (os.startsWith(WIN_PRE)) {
device = new WinDevice();
} else {
device = new LinuxDevice();
}
return device.getDeviceInfo();
}
}
获取设备信息的抽象类,将不同操作系统的通用信息获取方法抽象出来
public abstract class Device {
public DeviceInfo getDeviceInfo() throws Exception {
return new DeviceInfo()
.setIpList(this.getIpAddress())
.setMacList(this.getMacAddress())
.setCpu(this.getCpuSerial())
.setMainBoard(this.getMainBoardSerial());
}
List<String> getIpAddress() throws Exception {
List<InetAddress> inetAddresses = getLocalAllInetAddress();
return Optional.ofNullable(inetAddresses).orElse(new ArrayList<>(0))
.stream()
.map(e -> e.getHostAddress().toLowerCase())
.distinct()
.collect(Collectors.toList());
}
List<String> getMacAddress() throws Exception {
List<InetAddress> inetAddresses = getLocalAllInetAddress();
return Optional.ofNullable(inetAddresses).orElse(new ArrayList<>(0))
.stream()
.map(this::getMacByInetAddress)
.distinct()
.collect(Collectors.toList());
}
/**
* 获取 CpuSerial
*
* @return CpuSerial
* @throws Exception Exception
*/
abstract String getCpuSerial() throws Exception;
/**
* 获取 MainBoardSerial
*
* @return MainBoardSerial
* @throws Exception Exception
*/
abstract String getMainBoardSerial() throws Exception;
List<InetAddress> getLocalAllInetAddress() throws Exception {
List<InetAddress> inetAddressList = new ArrayList<>();
for (Enumeration<NetworkInterface> networkInterfaces = NetworkInterface.getNetworkInterfaces();
networkInterfaces.hasMoreElements(); ) {
NetworkInterface networkInterface = networkInterfaces.nextElement();
for (Enumeration<InetAddress> inetAddresses = networkInterface.getInetAddresses();
inetAddresses.hasMoreElements(); ) {
InetAddress inetAddr = inetAddresses.nextElement();
if (!inetAddr.isLoopbackAddress()
&& !inetAddr.isLinkLocalAddress()
&& !inetAddr.isMulticastAddress()) {
inetAddressList.add(inetAddr);
}
}
}
return inetAddressList;
}
String getMacByInetAddress(InetAddress inetAddr) {
try {
byte[] mac = NetworkInterface