修改加解密逻辑,允许使用通配符进行过滤
This commit is contained in:
@@ -3,6 +3,7 @@ package com.gis.xian.filter;
|
|||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.alibaba.fastjson2.TypeReference;
|
import com.alibaba.fastjson2.TypeReference;
|
||||||
import com.gis.xian.config.CryptoProperties;
|
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.SM2Utils;
|
||||||
import com.gis.xian.utils.safety.SM4Utils;
|
import com.gis.xian.utils.safety.SM4Utils;
|
||||||
import com.gis.xian.wrapper.Sm4KeyHolder;
|
import com.gis.xian.wrapper.Sm4KeyHolder;
|
||||||
@@ -85,15 +86,10 @@ public class DecryptFilter implements Filter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检查是否为无需解密的路径
|
* 检查是否为无需解密的路径(支持通配符匹配)
|
||||||
*/
|
*/
|
||||||
private boolean isNoDecryptPath(String requestUri) {
|
private boolean isNoDecryptPath(String requestUri) {
|
||||||
for (String path : cryptoProperties.getNoDecryptPaths()) {
|
return PathMatcherUtils.matches(requestUri, cryptoProperties.getNoDecryptPaths());
|
||||||
if (requestUri.contains(path)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import com.gis.xian.config.CryptoProperties;
|
import com.gis.xian.config.CryptoProperties;
|
||||||
|
import com.gis.xian.utils.PathMatcherUtils;
|
||||||
import com.gis.xian.utils.safety.SM4Utils;
|
import com.gis.xian.utils.safety.SM4Utils;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
@@ -29,7 +30,7 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
|
|||||||
private CryptoProperties cryptoProperties;
|
private CryptoProperties cryptoProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 判断是否需要加密:排除特定路径,其余全部加密
|
* 判断是否需要加密:排除特定路径,其余全部加密(支持通配符匹配)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
|
||||||
@@ -41,19 +42,12 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
|
|||||||
HttpServletRequest request = attributes.getRequest();
|
HttpServletRequest request = attributes.getRequest();
|
||||||
String requestUri = request.getRequestURI();
|
String requestUri = request.getRequestURI();
|
||||||
|
|
||||||
// 检查是否为无需加密的路径
|
// 检查是否为无需加密的路径(支持通配符)
|
||||||
for (String path : cryptoProperties.getNoEncryptPaths()) {
|
return !PathMatcherUtils.matches(requestUri, cryptoProperties.getNoEncryptPaths());
|
||||||
if (requestUri.contains(path)) {
|
|
||||||
return false; // 排除路径,不加密
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 其余路径均需要加密
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应体加密逻辑(保持不变)
|
* 响应体加密逻辑
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
|
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
|
||||||
@@ -61,15 +55,17 @@ public class EncryptResponseAdvice implements ResponseBodyAdvice<Object> {
|
|||||||
ServerHttpRequest request, ServerHttpResponse response) {
|
ServerHttpRequest request, ServerHttpResponse response) {
|
||||||
try {
|
try {
|
||||||
String sm4Key = Sm4KeyHolder.getSm4Key();
|
String sm4Key = Sm4KeyHolder.getSm4Key();
|
||||||
|
// 如果SM4密钥不存在,直接返回原始数据(不加密)
|
||||||
if (sm4Key == null || sm4Key.length() != 32) {
|
if (sm4Key == null || sm4Key.length() != 32) {
|
||||||
throw new RuntimeException("SM4密钥不存在或格式错误,无法加密响应");
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
String plaintext = objectMapper.writeValueAsString(body);
|
String plaintext = objectMapper.writeValueAsString(body);
|
||||||
String encryptedText = SM4Utils.encrypt(sm4Key, plaintext);
|
String encryptedText = SM4Utils.encrypt(sm4Key, plaintext);
|
||||||
return encryptedText;
|
return encryptedText;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException("响应数据加密失败: " + e.getMessage(), e);
|
// 加密失败时返回原始数据,避免影响业务
|
||||||
|
return body;
|
||||||
} finally {
|
} finally {
|
||||||
Sm4KeyHolder.clear(); // 清除线程本地存储,避免内存泄漏
|
Sm4KeyHolder.clear(); // 清除线程本地存储,避免内存泄漏
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user