diff --git a/nl-verify-check-sdk/pom.xml b/nl-verify-check-sdk/pom.xml
index 91d3fa3..3f0b88a 100644
--- a/nl-verify-check-sdk/pom.xml
+++ b/nl-verify-check-sdk/pom.xml
@@ -21,7 +21,7 @@
org.springframework.boot
spring-boot-starter-web
- 2.7.3
+ 2.6.4
org.projectlombok
@@ -29,11 +29,6 @@
1.18.22
compile
-
- com.alibaba
- fastjson
- 1.2.83
-
diff --git a/nl-verify-check-sdk/src/main/java/org/nl/core/AuthInterceptor.java b/nl-verify-check-sdk/src/main/java/org/nl/core/AuthInterceptor.java
index c6a0d64..ac694d9 100644
--- a/nl-verify-check-sdk/src/main/java/org/nl/core/AuthInterceptor.java
+++ b/nl-verify-check-sdk/src/main/java/org/nl/core/AuthInterceptor.java
@@ -1,51 +1,35 @@
package org.nl.core;
-import com.alibaba.fastjson.JSONObject;
-import org.nl.util.RSAUtil;
-import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
/**
* @Author: lyd
* @Date: 2025/8/26
*/
-public class AuthInterceptor extends HandlerInterceptorAdapter {
+public class AuthInterceptor implements HandlerInterceptor {
+ private final LicenseProperties properties;
+ private final LicenseVerifier verifier;
+ private final ObjectMapper objectMapper = new ObjectMapper();
+ public AuthInterceptor(LicenseProperties properties, LicenseVerifier verifier) {
+ this.properties = properties;
+ this.verifier = verifier;
+ }
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
- String authCode = request.getHeader("cdk"); // 假设从 Header 获取
-
- if (authCode == null || authCode.isEmpty()) {
- response.setContentType("text/html;charset=UTF-8");
- response.setStatus(402);
- response.getWriter().write(JSONObject.toJSONString(LicenseResult.requestResult(false, "请收入授权码", null)));
- return false;
+ String headerName = properties.getHeader();
+ String authCode = request.getHeader(headerName);
+ LicenseResult result = verifier.verify(authCode);
+ if (Boolean.TRUE.equals(result.getResult())) {
+ return true;
}
- String expirationStr ="";
- try {
- // 解密获取到期时间
- expirationStr = RSAUtil.decrypt(authCode);
- if ("-1".equals(expirationStr)) {
- return true;
- }
- LocalDate expirationDate = LocalDate.parse(expirationStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
- if (LocalDate.now().isAfter(expirationDate)) {
- response.setContentType("text/html;charset=UTF-8");
- response.setStatus(402);
- response.getWriter().write(JSONObject.toJSONString(LicenseResult.requestResult(false, "授权码已到期", null)));
- return false;
- }
- } catch (Exception e) {
- // 解密失败或格式错误
- response.setContentType("text/html;charset=UTF-8");
- response.setStatus(402);
- response.getWriter().write(JSONObject.toJSONString(LicenseResult.requestResult(false, "解密失败或格式错误", null)));
- return false;
- }
- return true;
+ response.setContentType("application/json;charset=UTF-8");
+ response.setStatus(402);
+ response.getWriter().write(objectMapper.writeValueAsString(result));
+ return false;
}
}
diff --git a/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseAutoConfiguration.java b/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseAutoConfiguration.java
new file mode 100644
index 0000000..ef867a4
--- /dev/null
+++ b/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseAutoConfiguration.java
@@ -0,0 +1,47 @@
+package org.nl.core;
+
+import org.nl.util.RSAUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+@Configuration
+@EnableConfigurationProperties(LicenseProperties.class)
+@ConditionalOnClass(WebMvcConfigurer.class)
+public class LicenseAutoConfiguration implements WebMvcConfigurer {
+
+ @Autowired
+ @Lazy
+ private AuthInterceptor authInterceptor;
+
+ @Bean
+ @ConditionalOnMissingBean
+ public RSAUtil rsaUtil(LicenseProperties properties) {
+ return new RSAUtil(properties.getPrivateKeyLocation());
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public LicenseVerifier licenseVerifier(RSAUtil rsaUtil) {
+ return new LicenseVerifier(rsaUtil);
+ }
+
+ @Bean
+ @ConditionalOnMissingBean
+ public AuthInterceptor authInterceptor(LicenseProperties properties, LicenseVerifier verifier) {
+ return new AuthInterceptor(properties, verifier);
+ }
+
+ @Override
+ public void addInterceptors(InterceptorRegistry registry) {
+ registry.addInterceptor(authInterceptor).addPathPatterns("/**");
+ }
+}
+
+
diff --git a/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseProperties.java b/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseProperties.java
new file mode 100644
index 0000000..e3dd872
--- /dev/null
+++ b/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseProperties.java
@@ -0,0 +1,32 @@
+package org.nl.core;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+/**
+ * 授权校验可配置属性
+ * @Author: lyd
+ * @Date: 2025/8/27
+ */
+@ConfigurationProperties(prefix = "nl.license")
+public class LicenseProperties {
+ /** header 名称,默认 cdk */
+ private String header = "cdk";
+ /** 私钥资源位置,默认 classpath:private_key.txt */
+ private String privateKeyLocation = "classpath:private_key.txt";
+
+ public String getHeader() {
+ return header;
+ }
+
+ public void setHeader(String header) {
+ this.header = header;
+ }
+
+ public String getPrivateKeyLocation() {
+ return privateKeyLocation;
+ }
+
+ public void setPrivateKeyLocation(String privateKeyLocation) {
+ this.privateKeyLocation = privateKeyLocation;
+ }
+}
diff --git a/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseVerifier.java b/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseVerifier.java
new file mode 100644
index 0000000..8085f05
--- /dev/null
+++ b/nl-verify-check-sdk/src/main/java/org/nl/core/LicenseVerifier.java
@@ -0,0 +1,37 @@
+package org.nl.core;
+
+import org.nl.util.RSAUtil;
+
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
+
+/**
+ * @Author: lyd
+ * @Date: 2025/8/27
+ */
+public class LicenseVerifier {
+ private final RSAUtil rsaUtil;
+
+ public LicenseVerifier(RSAUtil rsaUtil) {
+ this.rsaUtil = rsaUtil;
+ }
+
+ public LicenseResult verify(String authCode) {
+ if (authCode == null || authCode.isEmpty()) {
+ return LicenseResult.requestResult(false, "请输入授权码", null);
+ }
+ try {
+ String expirationStr = rsaUtil.decrypt(authCode);
+ if ("-1".equals(expirationStr)) {
+ return LicenseResult.requestOk("永久授权", expirationStr);
+ }
+ LocalDate expirationDate = LocalDate.parse(expirationStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+ if (LocalDate.now().isAfter(expirationDate)) {
+ return LicenseResult.requestResult(false, "授权码已到期", expirationStr);
+ }
+ return LicenseResult.requestOk("授权码有效", expirationStr);
+ } catch (Exception e) {
+ return LicenseResult.requestResult(false, "解密失败或格式错误", null);
+ }
+ }
+}
diff --git a/nl-verify-check-sdk/src/main/java/org/nl/core/WebConfig.java b/nl-verify-check-sdk/src/main/java/org/nl/core/WebConfig.java
deleted file mode 100644
index da45213..0000000
--- a/nl-verify-check-sdk/src/main/java/org/nl/core/WebConfig.java
+++ /dev/null
@@ -1,17 +0,0 @@
-package org.nl.core;
-
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-/**
- * @Author: lyd
- * @Date: 2025/8/26
- */
-@Configuration
-public class WebConfig implements WebMvcConfigurer {
- @Override
- public void addInterceptors(InterceptorRegistry registry) {
- registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
- }
-}
diff --git a/nl-verify-check-sdk/src/main/java/org/nl/util/RSAUtil.java b/nl-verify-check-sdk/src/main/java/org/nl/util/RSAUtil.java
index e67f8a8..d191a66 100644
--- a/nl-verify-check-sdk/src/main/java/org/nl/util/RSAUtil.java
+++ b/nl-verify-check-sdk/src/main/java/org/nl/util/RSAUtil.java
@@ -1,10 +1,16 @@
package org.nl.util;
+import org.springframework.core.io.DefaultResourceLoader;
+import org.springframework.core.io.Resource;
+import org.springframework.core.io.ResourceLoader;
import org.springframework.util.ResourceUtils;
import javax.crypto.Cipher;
import java.io.BufferedReader;
import java.io.FileReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;
@@ -15,31 +21,41 @@ import java.util.Base64;
* @Date: 2025/8/13
*/
public class RSAUtil {
- private static PrivateKey privateKey;
- public static synchronized PrivateKey getPrivateKey() throws Exception {
+ private final String privateKeyLocation;
+
+ private PrivateKey privateKey;
+
+ private final ResourceLoader resourceLoader = new DefaultResourceLoader();
+
+ public RSAUtil(String privateKeyLocation) {
+ this.privateKeyLocation = privateKeyLocation;
+ }
+
+
+ public synchronized PrivateKey getPrivateKey() throws Exception {
if (privateKey == null) {
- // 从 resources/private_key.txt 读取 Base64
- String filePath = ResourceUtils.getFile("classpath:private_key.txt").getPath();
- BufferedReader reader = new BufferedReader(new FileReader(filePath));
- StringBuilder sb = new StringBuilder();
- String line;
- while ((line = reader.readLine()) != null) {
- sb.append(line);
+ Resource resource = resourceLoader.getResource(privateKeyLocation);
+ try (InputStream is = resource.getInputStream();
+ InputStreamReader isr = new InputStreamReader(is, StandardCharsets.UTF_8);
+ BufferedReader reader = new BufferedReader(isr)) {
+ StringBuilder sb = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ sb.append(line.trim());
+ }
+ byte[] privateKeyBytes = Base64.getDecoder().decode(sb.toString());
+ PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
+ KeyFactory keyFactory = KeyFactory.getInstance("RSA");
+ privateKey = keyFactory.generatePrivate(keySpec);
}
- reader.close();
-
- byte[] privateKeyBytes = Base64.getDecoder().decode(sb.toString());
- PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
- KeyFactory keyFactory = KeyFactory.getInstance("RSA");
- privateKey = keyFactory.generatePrivate(keySpec);
}
return privateKey;
}
- public static String decrypt(String authCode) throws Exception {
+ public String decrypt(String authCode) throws Exception {
byte[] encryptedBytes = Base64.getDecoder().decode(authCode);
- Cipher cipher = Cipher.getInstance("RSA");
+ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.DECRYPT_MODE, getPrivateKey());
byte[] decrypted = cipher.doFinal(encryptedBytes);
return new String(decrypted, "UTF-8");
diff --git a/nl-verify-check-sdk/src/main/resources/META-INF/spring.factories b/nl-verify-check-sdk/src/main/resources/META-INF/spring.factories
new file mode 100644
index 0000000..477120b
--- /dev/null
+++ b/nl-verify-check-sdk/src/main/resources/META-INF/spring.factories
@@ -0,0 +1,4 @@
+org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
+org.nl.core.LicenseAutoConfiguration
+
+
diff --git a/nl-verify-check-test/src/main/java/org/nl/GenerateAuthCode.java b/nl-verify-check-test/src/main/java/org/nl/GenerateAuthCode.java
index 4679068..2dc0d35 100644
--- a/nl-verify-check-test/src/main/java/org/nl/GenerateAuthCode.java
+++ b/nl-verify-check-test/src/main/java/org/nl/GenerateAuthCode.java
@@ -22,8 +22,8 @@ public class GenerateAuthCode {
PublicKey publicKey = keyFactory.generatePublic(keySpec);
// 加密
-// Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 标准填充模式
- Cipher cipher = Cipher.getInstance("RSA"); // 标准填充模式
+ Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // 标准填充模式
+// Cipher cipher = Cipher.getInstance("RSA"); // 标准填充模式
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encrypted = cipher.doFinal(expirationDate.getBytes("UTF-8"));
String authCode = Base64.getEncoder().encodeToString(encrypted);
diff --git a/nl-verify-check-test/src/main/resources/application.yml b/nl-verify-check-test/src/main/resources/application.yml
new file mode 100644
index 0000000..c662588
--- /dev/null
+++ b/nl-verify-check-test/src/main/resources/application.yml
@@ -0,0 +1,3 @@
+nl:
+ license:
+ header: "cdk"
diff --git a/nl-verify-check-sdk/src/main/resources/private_key.txt b/nl-verify-check-test/src/main/resources/private_key.txt
similarity index 100%
rename from nl-verify-check-sdk/src/main/resources/private_key.txt
rename to nl-verify-check-test/src/main/resources/private_key.txt