From 622e6a0eb03f7e8f3f5164d525fc42999bd43504 Mon Sep 17 00:00:00 2001 From: cwchen <1048842385@qq.com> Date: Thu, 4 Sep 2025 18:30:42 +0800 Subject: [PATCH] =?UTF-8?q?=E9=98=B2=E9=87=8D=E6=94=BE=E6=94=BB=E5=87=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/filter/RequestCoverFilter.java | 108 ++++++++++++++---- .../framework/filter/ReplayAttackFilter.java | 2 +- 2 files changed, 85 insertions(+), 25 deletions(-) diff --git a/bonus-common/src/main/java/com/bonus/common/filter/RequestCoverFilter.java b/bonus-common/src/main/java/com/bonus/common/filter/RequestCoverFilter.java index d70dff0..803464d 100644 --- a/bonus-common/src/main/java/com/bonus/common/filter/RequestCoverFilter.java +++ b/bonus-common/src/main/java/com/bonus/common/filter/RequestCoverFilter.java @@ -273,8 +273,12 @@ public class RequestCoverFilter implements Filter { /** * 查询字符串包装类 */ + /** + * 查询字符串包装类(支持嵌套参数格式) + */ private static class QueryStringRequestWrapper extends HttpServletRequestWrapper { private final String queryString; + private Map cachedParameterMap; public QueryStringRequestWrapper(HttpServletRequest request, String queryString) { super(request); @@ -288,45 +292,101 @@ public class RequestCoverFilter implements Filter { @Override public String getParameter(String name) { - // 解析queryString获取参数值 - if (queryString != null) { - String[] pairs = queryString.split("&"); - for (String pair : pairs) { - String[] keyValue = pair.split("="); - if (keyValue.length == 2 && keyValue[0].equals(name)) { - return keyValue[1]; - } - } - } - return super.getParameter(name); + String[] values = getParameterMap().get(name); + return (values != null && values.length > 0) ? values[0] : null; } @Override public Map getParameterMap() { - // 解析queryString为参数Map - Map parameterMap = new HashMap<>(); - if (queryString != null) { - String[] pairs = queryString.split("&"); - for (String pair : pairs) { - String[] keyValue = pair.split("="); - if (keyValue.length == 2) { - parameterMap.put(keyValue[0], new String[]{keyValue[1]}); - } - } + if (cachedParameterMap == null) { + cachedParameterMap = parseNestedQueryString(queryString); } - return parameterMap; + return cachedParameterMap; } @Override public Enumeration getParameterNames() { - Map parameterMap = getParameterMap(); - return Collections.enumeration(parameterMap.keySet()); + return Collections.enumeration(getParameterMap().keySet()); } @Override public String[] getParameterValues(String name) { return getParameterMap().get(name); } + + /** + * 解析嵌套查询字符串为Map,支持 params[beginTime] 格式 + */ + private Map parseNestedQueryString(String queryString) { + Map parameterMap = new HashMap<>(); + if (queryString != null) { + try { + // 先URL解码 + String decodedQueryString = java.net.URLDecoder.decode(queryString, StandardCharsets.UTF_8.name()); + String[] pairs = decodedQueryString.split("&"); + + for (String pair : pairs) { + String[] keyValue = pair.split("=", 2); + if (keyValue.length == 2) { + String key = keyValue[0]; + String value = keyValue[1]; + + // 处理嵌套参数格式(如 params[beginTime]) + if (key.startsWith("params[") && key.endsWith("]")) { + // 提取嵌套参数名,如从 "params[beginTime]" 提取 "beginTime" + String nestedKey = key.substring(7, key.length() - 1); + + // 将嵌套参数转换为 params. 前缀的参数 + String paramsKey = nestedKey; + parameterMap.put(paramsKey, new String[]{value}); + } else { + // 普通参数处理 + if (parameterMap.containsKey(key)) { + String[] existingValues = parameterMap.get(key); + String[] newValues = Arrays.copyOf(existingValues, existingValues.length + 1); + newValues[existingValues.length] = value; + parameterMap.put(key, newValues); + } else { + parameterMap.put(key, new String[]{value}); + } + } + } + } + + } catch (Exception e) { + log.warn("解析嵌套查询字符串失败,使用简单解析: {}", e.getMessage()); + return parseSimpleQueryString(queryString); + } + } + return parameterMap; + } + + /** + * 简单解析查询字符串(备用方案) + */ + private Map parseSimpleQueryString(String queryString) { + Map parameterMap = new HashMap<>(); + if (queryString != null) { + String[] pairs = queryString.split("&"); + for (String pair : pairs) { + String[] keyValue = pair.split("=", 2); + if (keyValue.length == 2) { + String key = keyValue[0]; + String value = keyValue[1]; + + if (parameterMap.containsKey(key)) { + String[] existingValues = parameterMap.get(key); + String[] newValues = Arrays.copyOf(existingValues, existingValues.length + 1); + newValues[existingValues.length] = value; + parameterMap.put(key, newValues); + } else { + parameterMap.put(key, new String[]{value}); + } + } + } + } + return parameterMap; + } } } diff --git a/bonus-framework/src/main/java/com/bonus/framework/filter/ReplayAttackFilter.java b/bonus-framework/src/main/java/com/bonus/framework/filter/ReplayAttackFilter.java index 8d11813..a6c165c 100644 --- a/bonus-framework/src/main/java/com/bonus/framework/filter/ReplayAttackFilter.java +++ b/bonus-framework/src/main/java/com/bonus/framework/filter/ReplayAttackFilter.java @@ -172,7 +172,7 @@ public class ReplayAttackFilter implements Filter { // 构建待签名字符串 String signString = buildSignString(encryptUserId, timestamp, requestUrl, request.getMethod()); - + System.err.println(signString); // 使用HMAC-SHA256计算签名 String calculatedSignature = calculateHMAC(signString, encryptSecret);