Преглед на файлове

Update 优化接口访问日志,排除敏感参数输出

Yue преди 1 седмица
родител
ревизия
6df9e10853

+ 5 - 0
SERVER/VberAdminPlusV3/vber-common/vber-common-core/src/main/java/com/vber/common/core/constant/SystemConstants.java

@@ -163,4 +163,9 @@ public interface SystemConstants {
      * 默认组织机构 ID
      * 默认组织机构 ID
      */
      */
     Long DEFAULT_ORG_ID = 100L;
     Long DEFAULT_ORG_ID = 100L;
+
+    /**
+     * 排除敏感属性字段
+     */
+    String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
 }
 }

+ 15 - 16
SERVER/VberAdminPlusV3/vber-common/vber-common-log/src/main/java/com/vber/common/log/aspect/LogAspect.java

@@ -4,6 +4,8 @@ import cn.hutool.core.lang.Dict;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
+
+import com.vber.common.core.constant.SystemConstants;
 import com.vber.common.core.domain.model.LoginUser;
 import com.vber.common.core.domain.model.LoginUser;
 import com.vber.common.core.utils.ServletUtils;
 import com.vber.common.core.utils.ServletUtils;
 import com.vber.common.core.utils.SpringUtils;
 import com.vber.common.core.utils.SpringUtils;
@@ -40,15 +42,9 @@ import java.util.*;
 public class LogAspect {
 public class LogAspect {
 
 
     /**
     /**
-     * 排除敏感属性字段
-     */
-    public static final String[] EXCLUDE_PROPERTIES = {"password", "oldPassword", "newPassword", "confirmPassword"};
-
-
-    /**
-     * 计算操作消耗时间
+     * 计时 key
      */
      */
-    private static final ThreadLocal<StopWatch> TIME_THREADLOCAL = new ThreadLocal<>();
+    private static final ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>();
 
 
     /**
     /**
      * 处理请求前执行
      * 处理请求前执行
@@ -56,7 +52,7 @@ public class LogAspect {
     @Before(value = "@annotation(controllerLog)")
     @Before(value = "@annotation(controllerLog)")
     public void doBefore(JoinPoint joinPoint, Log controllerLog) {
     public void doBefore(JoinPoint joinPoint, Log controllerLog) {
         StopWatch stopWatch = new StopWatch();
         StopWatch stopWatch = new StopWatch();
-        TIME_THREADLOCAL.set(stopWatch);
+        KEY_CACHE.set(stopWatch);
         stopWatch.start();
         stopWatch.start();
     }
     }
 
 
@@ -109,7 +105,7 @@ public class LogAspect {
             // 处理设置注解上的参数
             // 处理设置注解上的参数
             getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
             getControllerMethodDescription(joinPoint, controllerLog, operLog, jsonResult);
             // 设置消耗时间
             // 设置消耗时间
-            StopWatch stopWatch = TIME_THREADLOCAL.get();
+            StopWatch stopWatch = KEY_CACHE.get();
             stopWatch.stop();
             stopWatch.stop();
             operLog.setCostTime(stopWatch.getDuration().toMillis());
             operLog.setCostTime(stopWatch.getDuration().toMillis());
             // 发布事件保存数据库
             // 发布事件保存数据库
@@ -118,7 +114,7 @@ public class LogAspect {
             // 记录本地异常日志
             // 记录本地异常日志
             log.error("异常信息:{}", exp.getMessage());
             log.error("异常信息:{}", exp.getMessage());
         } finally {
         } finally {
-            TIME_THREADLOCAL.remove();
+            KEY_CACHE.remove();
         }
         }
     }
     }
 
 
@@ -129,7 +125,8 @@ public class LogAspect {
      * @param operLog 操作日志
      * @param operLog 操作日志
      * @throws Exception
      * @throws Exception
      */
      */
-    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult) throws Exception {
+    public void getControllerMethodDescription(JoinPoint joinPoint, Log log, OperLogEvent operLog, Object jsonResult)
+            throws Exception {
         // 设置action动作
         // 设置action动作
         operLog.setBusinessType(log.businessType().ordinal());
         operLog.setBusinessType(log.businessType().ordinal());
         // 设置标题
         // 设置标题
@@ -153,14 +150,16 @@ public class LogAspect {
      * @param operLog 操作日志
      * @param operLog 操作日志
      * @throws Exception 异常
      * @throws Exception 异常
      */
      */
-    private void setRequestValue(JoinPoint joinPoint, OperLogEvent operLog, String[] excludeParamNames) throws Exception {
+    private void setRequestValue(JoinPoint joinPoint, OperLogEvent operLog, String[] excludeParamNames)
+            throws Exception {
         Map<String, String> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
         Map<String, String> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
         String requestMethod = operLog.getRequestMethod();
         String requestMethod = operLog.getRequestMethod();
-        if (MapUtil.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name())) {
+        if (MapUtil.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(),
+                HttpMethod.POST.name(), HttpMethod.DELETE.name())) {
             String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
             String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
             operLog.setOperParam(StringUtils.substring(params, 0, 3800));
             operLog.setOperParam(StringUtils.substring(params, 0, 3800));
         } else {
         } else {
-            MapUtil.removeAny(paramsMap, EXCLUDE_PROPERTIES);
+            MapUtil.removeAny(paramsMap, SystemConstants.EXCLUDE_PROPERTIES);
             MapUtil.removeAny(paramsMap, excludeParamNames);
             MapUtil.removeAny(paramsMap, excludeParamNames);
             operLog.setOperParam(StringUtils.substring(JsonUtils.toJsonString(paramsMap), 0, 3800));
             operLog.setOperParam(StringUtils.substring(JsonUtils.toJsonString(paramsMap), 0, 3800));
         }
         }
@@ -174,7 +173,7 @@ public class LogAspect {
         if (ArrayUtil.isEmpty(paramsArray)) {
         if (ArrayUtil.isEmpty(paramsArray)) {
             return params.toString();
             return params.toString();
         }
         }
-        String[] exclude = ArrayUtil.addAll(excludeParamNames, EXCLUDE_PROPERTIES);
+        String[] exclude = ArrayUtil.addAll(excludeParamNames, SystemConstants.EXCLUDE_PROPERTIES);
         for (Object o : paramsArray) {
         for (Object o : paramsArray) {
             if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) {
             if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) {
                 String str = "";
                 String str = "";

+ 50 - 19
SERVER/VberAdminPlusV3/vber-common/vber-common-web/src/main/java/com/vber/common/web/interceptor/PlusWebInvokeTimeInterceptor.java

@@ -2,24 +2,30 @@ package com.vber.common.web.interceptor;
 
 
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.io.IoUtil;
 import cn.hutool.core.map.MapUtil;
 import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ArrayUtil;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.core.util.ObjectUtil;
-import com.vber.common.core.constant.GlobalConstants;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ArrayNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.vber.common.core.constant.SystemConstants;
 import com.vber.common.core.utils.StringUtils;
 import com.vber.common.core.utils.StringUtils;
 import com.vber.common.json.utils.JsonUtils;
 import com.vber.common.json.utils.JsonUtils;
-import com.vber.common.tenant.helper.TenantHelper;
 import com.vber.common.web.filter.RepeatedlyRequestWrapper;
 import com.vber.common.web.filter.RepeatedlyRequestWrapper;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletRequest;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.extern.slf4j.Slf4j;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.time.StopWatch;
 import org.apache.commons.lang3.time.StopWatch;
 import org.springframework.http.MediaType;
 import org.springframework.http.MediaType;
-import org.springframework.lang.NonNull;
 import org.springframework.lang.Nullable;
 import org.springframework.lang.Nullable;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.HandlerInterceptor;
 import org.springframework.web.servlet.ModelAndView;
 import org.springframework.web.servlet.ModelAndView;
 
 
-import java.io.BufferedReader;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map;
+import java.util.Set;
 
 
 /**
 /**
  * web的调用时间统计拦截器
  * web的调用时间统计拦截器
@@ -32,27 +38,28 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
     private final static ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>();
     private final static ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>();
 
 
     @Override
     @Override
-    public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
-                             @NonNull Object handler)
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
             throws Exception {
             throws Exception {
         String url = request.getMethod() + " " + request.getRequestURI();
         String url = request.getMethod() + " " + request.getRequestURI();
-        // 请求头获取到租户id,设置动态租户
-        String tenantId = request.getHeader(GlobalConstants.TENANT_ID_HEADER);
-        if (!StringUtils.isBlank(tenantId)) {
-            TenantHelper.setDynamic(tenantId);
-        }
         // 打印请求参数
         // 打印请求参数
         if (isJsonRequest(request)) {
         if (isJsonRequest(request)) {
             String jsonParam = "";
             String jsonParam = "";
             if (request instanceof RepeatedlyRequestWrapper) {
             if (request instanceof RepeatedlyRequestWrapper) {
-                BufferedReader reader = request.getReader();
-                jsonParam = IoUtil.read(reader);
+                jsonParam = IoUtil.read(request.getReader());
+                if (StringUtils.isNotBlank(jsonParam)) {
+                    ObjectMapper objectMapper = JsonUtils.getObjectMapper();
+                    JsonNode rootNode = objectMapper.readTree(jsonParam);
+                    removeSensitiveFields(rootNode, SystemConstants.EXCLUDE_PROPERTIES);
+                    jsonParam = rootNode.toString();
+                }
             }
             }
             log.info("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
             log.info("[PLUS]开始请求 => URL[{}],参数类型[json],参数:[{}]", url, jsonParam);
         } else {
         } else {
             Map<String, String[]> parameterMap = request.getParameterMap();
             Map<String, String[]> parameterMap = request.getParameterMap();
             if (MapUtil.isNotEmpty(parameterMap)) {
             if (MapUtil.isNotEmpty(parameterMap)) {
-                String parameters = JsonUtils.toJsonString(parameterMap);
+                Map<String, String[]> map = new LinkedHashMap<>(parameterMap);
+                MapUtil.removeAny(map, SystemConstants.EXCLUDE_PROPERTIES);
+                String parameters = JsonUtils.toJsonString(map);
                 log.info("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
                 log.info("[PLUS]开始请求 => URL[{}],参数类型[param],参数:[{}]", url, parameters);
             } else {
             } else {
                 log.info("[PLUS]开始请求 => URL[{}],无参数", url);
                 log.info("[PLUS]开始请求 => URL[{}],无参数", url);
@@ -62,19 +69,43 @@ public class PlusWebInvokeTimeInterceptor implements HandlerInterceptor {
         StopWatch stopWatch = new StopWatch();
         StopWatch stopWatch = new StopWatch();
         KEY_CACHE.set(stopWatch);
         KEY_CACHE.set(stopWatch);
         stopWatch.start();
         stopWatch.start();
+
         return true;
         return true;
     }
     }
 
 
+    private void removeSensitiveFields(JsonNode node, String[] excludeProperties) {
+        if (node == null) {
+            return;
+        }
+        if (node.isObject()) {
+            ObjectNode objectNode = (ObjectNode) node;
+            // 收集要删除的字段名(避免 ConcurrentModification)
+            Set<String> fieldsToRemove = new HashSet<>();
+            objectNode.fieldNames().forEachRemaining(fieldName -> {
+                if (ArrayUtil.contains(excludeProperties, fieldName)) {
+                    fieldsToRemove.add(fieldName);
+                }
+            });
+            fieldsToRemove.forEach(objectNode::remove);
+            // 递归处理子节点
+            objectNode.elements().forEachRemaining(child -> removeSensitiveFields(child, excludeProperties));
+        } else if (node.isArray()) {
+            ArrayNode arrayNode = (ArrayNode) node;
+            for (JsonNode child : arrayNode) {
+                removeSensitiveFields(child, excludeProperties);
+            }
+        }
+    }
+
     @Override
     @Override
-    public void postHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
-                           @NonNull Object handler,
-                           @Nullable ModelAndView modelAndView) throws Exception {
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
+            @Nullable ModelAndView modelAndView) throws Exception {
 
 
     }
     }
 
 
     @Override
     @Override
-    public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response,
-                                @NonNull Object handler, @Nullable Exception ex)
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
+            @Nullable Exception ex)
             throws Exception {
             throws Exception {
         StopWatch stopWatch = KEY_CACHE.get();
         StopWatch stopWatch = KEY_CACHE.get();
         if (ObjectUtil.isNotNull(stopWatch)) {
         if (ObjectUtil.isNotNull(stopWatch)) {