From 2622d9147e2b4a003b9b51ec3410870921fc837e Mon Sep 17 00:00:00 2001 From: ayi <17325218783@163.com> Date: Mon, 7 Jul 2025 11:10:52 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20@NoSensitive=20=E6=B3=A8?= =?UTF-8?q?=E8=A7=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 SysUser 实体类中为手机号码字段添加 @Sensitive 注解 - 新增 @NoSensitive 注解和相关切面、拦截器,用于 “关闭” 数据脱敏 - 在用户信息相关接口中添加 @NoSensitive 注解,以 “关闭” 数据脱敏 - 新增 WebMvcConfig 配置类,注册 NoSensitiveInterceptor 拦截器 --- ruoyi-api/ruoyi-api-system/pom.xml | 7 ++- .../ruoyi/system/api/RemoteLogService.java | 2 + .../ruoyi/system/api/RemoteUserService.java | 2 + .../com/ruoyi/system/api/domain/SysUser.java | 5 +++ .../common/core/annotation/NoSensitive.java | 15 +++++++ .../common/core/aspect/NoSensitiveAspect.java | 29 +++++++++++++ .../core/context/SensitiveContextHolder.java | 36 ++++++++++++++++ .../interceptor/NoSensitiveInterceptor.java | 43 +++++++++++++++++++ .../config/SensitiveJsonSerializer.java | 3 +- ruoyi-modules/ruoyi-system/pom.xml | 5 +++ .../java/com/ruoyi/system/WebMvcConfig.java | 23 ++++++++++ .../controller/SysProfileController.java | 3 ++ .../system/controller/SysUserController.java | 5 +++ 13 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/NoSensitive.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/NoSensitiveAspect.java create mode 100644 ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SensitiveContextHolder.java create mode 100644 ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/NoSensitiveInterceptor.java create mode 100644 ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/WebMvcConfig.java diff --git a/ruoyi-api/ruoyi-api-system/pom.xml b/ruoyi-api/ruoyi-api-system/pom.xml index 47f0207d..62ba0ee2 100644 --- a/ruoyi-api/ruoyi-api-system/pom.xml +++ b/ruoyi-api/ruoyi-api-system/pom.xml @@ -22,7 +22,12 @@ com.ruoyi ruoyi-common-core - + + + + com.ruoyi + ruoyi-common-sensitive + \ No newline at end of file diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java index 3402afad..d87faeec 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteLogService.java @@ -1,5 +1,6 @@ package com.ruoyi.system.api; +import com.ruoyi.common.core.annotation.NoSensitive; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; @@ -16,6 +17,7 @@ import com.ruoyi.system.api.factory.RemoteLogFallbackFactory; * * @author ruoyi */ +@NoSensitive @FeignClient(contextId = "remoteLogService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteLogFallbackFactory.class) public interface RemoteLogService { diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java index c1a94b3d..1c10d2dd 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteUserService.java @@ -1,5 +1,6 @@ package com.ruoyi.system.api; +import com.ruoyi.common.core.annotation.NoSensitive; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @@ -19,6 +20,7 @@ import com.ruoyi.system.api.model.LoginUser; * * @author ruoyi */ +@NoSensitive @FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE, fallbackFactory = RemoteUserFallbackFactory.class) public interface RemoteUserService { diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java index 0658deef..002cc11b 100644 --- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java +++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysUser.java @@ -3,6 +3,10 @@ package com.ruoyi.system.api.domain; import java.util.Date; import java.util.List; import javax.validation.constraints.*; + +import com.ruoyi.common.core.annotation.NoSensitive; +import com.ruoyi.common.sensitive.annotation.Sensitive; +import com.ruoyi.common.sensitive.enums.DesensitizedType; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import com.ruoyi.common.core.annotation.Excel; @@ -44,6 +48,7 @@ public class SysUser extends BaseEntity /** 手机号码 */ @Excel(name = "手机号码", cellType = ColumnType.TEXT) + @Sensitive(desensitizedType = DesensitizedType.PHONE) private String phonenumber; /** 用户性别 */ diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/NoSensitive.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/NoSensitive.java new file mode 100644 index 00000000..6a2def79 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/annotation/NoSensitive.java @@ -0,0 +1,15 @@ +package com.ruoyi.common.core.annotation; + +import java.lang.annotation.*; + +/** + * @Description “关闭” 数据脱敏 + * @Author AhYi + * @Date 2025-07-07 10:23 + */ + +@Target({ElementType.TYPE, ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +@Documented +public @interface NoSensitive { +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/NoSensitiveAspect.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/NoSensitiveAspect.java new file mode 100644 index 00000000..a6443682 --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/aspect/NoSensitiveAspect.java @@ -0,0 +1,29 @@ +package com.ruoyi.common.core.aspect; + +import com.ruoyi.common.core.annotation.NoSensitive; +import com.ruoyi.common.core.context.SensitiveContextHolder; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.springframework.stereotype.Component; + +/** + * @Description @NoSensitive 注解切面,主要用户对方法的注解 + * @Author AhYi + * @Date 2025-07-07 10:31 + */ + +@Aspect +@Component +public class NoSensitiveAspect { + + @Around("@annotation(noSensitive)") + public Object around(ProceedingJoinPoint joinPoint, NoSensitive noSensitive) throws Throwable { + try { + SensitiveContextHolder.enterNoSensitiveScope(); + return joinPoint.proceed(); + } finally { + SensitiveContextHolder.exitNoSensitiveScope(); + } + } +} diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SensitiveContextHolder.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SensitiveContextHolder.java new file mode 100644 index 00000000..b56ab1ca --- /dev/null +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/context/SensitiveContextHolder.java @@ -0,0 +1,36 @@ +package com.ruoyi.common.core.context; + +/** + * @Description Sensitive 数据脱敏上下文管理,存储当前线程是否需要脱敏 + * @Author AhYi + * @Date 2025-07-07 10:27 + */ + + +public class SensitiveContextHolder { + private static final ThreadLocal COUNTER = new ThreadLocal<>(); + + public static void enterNoSensitiveScope() { + Integer count = COUNTER.get(); + if (count == null) { + count = 0; + } + COUNTER.set(count + 1); + } + + public static void exitNoSensitiveScope() { + Integer count = COUNTER.get(); + if (count != null) { + if (count <= 1) { + COUNTER.remove(); + } else { + COUNTER.set(count - 1); + } + } + } + + public static boolean isNoSensitiveScope() { + Integer count = COUNTER.get(); + return count != null && count > 0; + } +} diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/NoSensitiveInterceptor.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/NoSensitiveInterceptor.java new file mode 100644 index 00000000..2c7d5fca --- /dev/null +++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/interceptor/NoSensitiveInterceptor.java @@ -0,0 +1,43 @@ +package com.ruoyi.common.security.interceptor; + +import com.ruoyi.common.core.annotation.NoSensitive; +import com.ruoyi.common.core.context.SensitiveContextHolder; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @Description @NoSensitive 注解的请求拦截器,主要用于对请求的注解,在请求的整个生命周期内有效 + * @Author AhYi + * @Date 2025-07-07 10:35 + */ + +public class NoSensitiveInterceptor implements HandlerInterceptor { + private static final String SENSITIVE_INTERCEPTOR_APPLIED = "SENSITIVE_INTERCEPTOR_APPLIED"; + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { + if (handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + NoSensitive noSensitive = handlerMethod.getMethodAnnotation(NoSensitive.class); + if (noSensitive == null) { + noSensitive = handlerMethod.getBeanType().getAnnotation(NoSensitive.class); + } + if (noSensitive != null) { + SensitiveContextHolder.enterNoSensitiveScope(); + request.setAttribute(SENSITIVE_INTERCEPTOR_APPLIED, Boolean.TRUE); + } + } + return true; + } + + @Override + public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { + Object applied = request.getAttribute(SENSITIVE_INTERCEPTOR_APPLIED); + if (applied != null && (Boolean) applied) { + SensitiveContextHolder.exitNoSensitiveScope(); + } + } +} diff --git a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/config/SensitiveJsonSerializer.java b/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/config/SensitiveJsonSerializer.java index cbb0d7eb..5f7dd2ef 100644 --- a/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/config/SensitiveJsonSerializer.java +++ b/ruoyi-common/ruoyi-common-sensitive/src/main/java/com/ruoyi/common/sensitive/config/SensitiveJsonSerializer.java @@ -10,6 +10,7 @@ import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.context.SecurityContextHolder; +import com.ruoyi.common.core.context.SensitiveContextHolder; import com.ruoyi.common.sensitive.annotation.Sensitive; import com.ruoyi.common.sensitive.enums.DesensitizedType; @@ -25,7 +26,7 @@ public class SensitiveJsonSerializer extends JsonSerializer implements C @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { - if (desensitization()) + if (desensitization() && !SensitiveContextHolder.isNoSensitiveScope()) { gen.writeString(desensitizedType.desensitizer().apply(value)); } diff --git a/ruoyi-modules/ruoyi-system/pom.xml b/ruoyi-modules/ruoyi-system/pom.xml index 63821116..48cf7178 100644 --- a/ruoyi-modules/ruoyi-system/pom.xml +++ b/ruoyi-modules/ruoyi-system/pom.xml @@ -71,6 +71,11 @@ ruoyi-common-swagger + + + com.ruoyi + ruoyi-common-sensitive + diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/WebMvcConfig.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/WebMvcConfig.java new file mode 100644 index 00000000..36661fe1 --- /dev/null +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/WebMvcConfig.java @@ -0,0 +1,23 @@ +package com.ruoyi.system; + +import com.ruoyi.common.security.interceptor.NoSensitiveInterceptor; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.InterceptorRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +/** + * @Description WebMvcConfig + * @Author AhYi + * @Date 2025-07-07 10:46 + */ + +@Configuration +public class WebMvcConfig implements WebMvcConfigurer { + + @Override + public void addInterceptors(InterceptorRegistry registry) { + registry.addInterceptor(new NoSensitiveInterceptor()) + .addPathPatterns("/**") + .order(-1); + } +} diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java index 83aab06a..b16a110c 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java @@ -2,6 +2,8 @@ package com.ruoyi.system.controller; import java.util.Arrays; import java.util.Map; + +import com.ruoyi.common.core.annotation.NoSensitive; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; @@ -49,6 +51,7 @@ public class SysProfileController extends BaseController /** * 个人信息 */ + @NoSensitive @GetMapping public AjaxResult profile() { diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java index eac60ee3..5bf3a8c1 100644 --- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java +++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserController.java @@ -6,6 +6,8 @@ import java.util.List; import java.util.Set; import java.util.stream.Collectors; import javax.servlet.http.HttpServletResponse; + +import com.ruoyi.common.core.annotation.NoSensitive; import org.apache.commons.lang3.ArrayUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; @@ -117,6 +119,7 @@ public class SysUserController extends BaseController /** * 获取当前用户信息 */ + @NoSensitive @InnerAuth @GetMapping("/info/{username}") public R info(@PathVariable("username") String username) @@ -171,6 +174,7 @@ public class SysUserController extends BaseController * * @return 用户信息 */ + @NoSensitive @GetMapping("getInfo") public AjaxResult getInfo() { @@ -221,6 +225,7 @@ public class SysUserController extends BaseController /** * 根据用户编号获取详细信息 */ + @NoSensitive @RequiresPermissions("system:user:query") @GetMapping(value = { "/", "/{userId}" }) public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)