修改加解密逻辑,允许使用通配符进行过滤

This commit is contained in:
wzy-warehouse
2026-05-18 10:16:26 +08:00
parent 2b40f2e13b
commit e4e3a09c47
3 changed files with 50 additions and 20 deletions
@@ -3,6 +3,7 @@ package com.gis.xian.filter;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.TypeReference;
import com.gis.xian.config.CryptoProperties;
import com.gis.xian.utils.PathMatcherUtils;
import com.gis.xian.utils.safety.SM2Utils;
import com.gis.xian.utils.safety.SM4Utils;
import com.gis.xian.wrapper.Sm4KeyHolder;
@@ -85,15 +86,10 @@ public class DecryptFilter implements Filter {
}
/**
* 检查是否为无需解密的路径
* 检查是否为无需解密的路径(支持通配符匹配)
*/
private boolean isNoDecryptPath(String requestUri) {
for (String path : cryptoProperties.getNoDecryptPaths()) {
if (requestUri.contains(path)) {
return true;
}
}
return false;
return PathMatcherUtils.matches(requestUri, cryptoProperties.getNoDecryptPaths());
}
/**
@@ -0,0 +1,38 @@
package com.gis.xian.utils;
import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import java.util.List;
/**
* 路径匹配工具类
* 支持 Ant 风格通配符:
* - ? 匹配一个字符
* - * 匹配零个或多个字符(不包括路径分隔符)
* - ** 匹配零个或多个目录
*/
public class PathMatcherUtils {
private static final PathMatcher pathMatcher = new AntPathMatcher();
/**
* 检查请求路径是否匹配给定的模式列表
*
* @param requestUri 请求URI
* @param patterns 通配符模式列表
* @return 如果匹配返回true,否则返回false
*/
public static boolean matches(String requestUri, List<String> patterns) {
if (patterns == null || patterns.isEmpty()) {
return false;
}
for (String pattern : patterns) {
if (pathMatcher.match(pattern, requestUri)) {
return true;
}
}
return false;
}
}
@@ -2,6 +2,7 @@ package com.gis.xian.wrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.gis.xian.config.CryptoProperties;
import com.gis.xian.utils.PathMatcherUtils;
import com.gis.xian.utils.safety.SM4Utils;
import jakarta.annotation.Resource;
import org.springframework.core.MethodParameter;
@@ -29,7 +30,7 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
private CryptoProperties cryptoProperties;
/**
* 判断是否需要加密:排除特定路径,其余全部加密
* 判断是否需要加密:排除特定路径,其余全部加密(支持通配符匹配)
*/
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
@@ -41,19 +42,12 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
HttpServletRequest request = attributes.getRequest();
String requestUri = request.getRequestURI();
// 检查是否为无需加密的路径
for (String path : cryptoProperties.getNoEncryptPaths()) {
if (requestUri.contains(path)) {
return false; // 排除路径,不加密
}
}
// 其余路径均需要加密
return true;
// 检查是否为无需加密的路径(支持通配符)
return !PathMatcherUtils.matches(requestUri, cryptoProperties.getNoEncryptPaths());
}
/**
* 响应体加密逻辑(保持不变)
* 响应体加密逻辑
*/
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
@@ -61,15 +55,17 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
ServerHttpRequest request, ServerHttpResponse response) {
try {
String sm4Key = Sm4KeyHolder.getSm4Key();
// 如果SM4密钥不存在,直接返回原始数据(不加密)
if (sm4Key == null || sm4Key.length() != 32) {
throw new RuntimeException("SM4密钥不存在或格式错误,无法加密响应");
return body;
}
String plaintext = objectMapper.writeValueAsString(body);
String encryptedText = SM4Utils.encrypt(sm4Key, plaintext);
return encryptedText;
} catch (Exception e) {
throw new RuntimeException("响应数据加密失败: " + e.getMessage(), e);
// 加密失败时返回原始数据,避免影响业务
return body;
} finally {
Sm4KeyHolder.clear(); // 清除线程本地存储,避免内存泄漏
}