src/main/java/com/ruoyi/common/utils/DesensitizedUtil.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ruoyi/common/utils/StringUtils.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Sensitive.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ruoyi/framework/aspectj/lang/enums/DesensitizedType.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/main/java/com/ruoyi/framework/config/SensitiveJsonSerializer.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
src/main/java/com/ruoyi/common/utils/DesensitizedUtil.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,49 @@ package com.ruoyi.common.utils; /** * è±æå·¥å ·ç±» * * @author ruoyi */ public class DesensitizedUtil { /** * å¯ç çå ¨é¨å符é½ç¨*代æ¿ï¼æ¯å¦ï¼****** * * @param password å¯ç * @return è±æåçå¯ç */ public static String password(String password) { if (StringUtils.isBlank(password)) { return StringUtils.EMPTY; } return StringUtils.repeat('*', password.length()); } /** * 车çä¸é´ç¨*代æ¿ï¼å¦ææ¯é误ç车çï¼ä¸å¤ç * * @param carLicense 宿´ç车çå· * @return è±æåç车ç */ public static String carLicense(String carLicense) { if (StringUtils.isBlank(carLicense)) { return StringUtils.EMPTY; } // æ®é车ç if (carLicense.length() == 7) { carLicense = StringUtils.hide(carLicense, 3, 6); } else if (carLicense.length() == 8) { // æ°è½æºè½¦ç carLicense = StringUtils.hide(carLicense, 3, 7); } return carLicense; } } src/main/java/com/ruoyi/common/utils/StringUtils.java
@@ -23,6 +23,9 @@ /** ä¸å线 */ private static final char SEPARATOR = '_'; /** æå· */ private static final char ASTERISK = '*'; /** * è·ååæ°ä¸ä¸ºç©ºå¼ * @@ -164,6 +167,49 @@ } /** * æ¿æ¢æå®å符串çæå®åºé´å å符为"*" * * @param str å符串 * @param startInclude å¼å§ä½ç½®ï¼å å«ï¼ * @param endExclude ç»æä½ç½®ï¼ä¸å å«ï¼ * @return æ¿æ¢åçå符串 */ public static String hide(CharSequence str, int startInclude, int endExclude) { if (isEmpty(str)) { return NULLSTR; } final int strLength = str.length(); if (startInclude > strLength) { return NULLSTR; } if (endExclude > strLength) { endExclude = strLength; } if (startInclude > endExclude) { // å¦æèµ·å§ä½ç½®å¤§äºç»æä½ç½®ï¼ä¸æ¿æ¢ return NULLSTR; } final char[] chars = new char[strLength]; for (int i = 0; i < strLength; i++) { if (i >= startInclude && i < endExclude) { chars[i] = ASTERISK; } else { chars[i] = str.charAt(i); } } return new String(chars); } /** * æªåå符串 * * @param str å符串 src/main/java/com/ruoyi/framework/aspectj/lang/annotation/Sensitive.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,24 @@ package com.ruoyi.framework.aspectj.lang.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.ruoyi.framework.aspectj.lang.enums.DesensitizedType; import com.ruoyi.framework.config.SensitiveJsonSerializer; /** * æ°æ®è±ææ³¨è§£ * * @author ruoyi */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using = SensitiveJsonSerializer.class) public @interface Sensitive { DesensitizedType desensitizedType(); } src/main/java/com/ruoyi/framework/aspectj/lang/enums/DesensitizedType.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,59 @@ package com.ruoyi.framework.aspectj.lang.enums; import java.util.function.Function; import com.ruoyi.common.utils.DesensitizedUtil; /** * è±æç±»å * * @author ruoyi */ public enum DesensitizedType { /** * å§åï¼ç¬¬2使巿¿æ¢ */ USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), /** * å¯ç ï¼å ¨é¨å符é½ç¨*ä»£æ¿ */ PASSWORD(DesensitizedUtil::password), /** * 身份è¯ï¼ä¸é´10使巿¿æ¢ */ ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")), /** * ææºå·ï¼ä¸é´4使巿¿æ¢ */ PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), /** * çµåé®ç®±ï¼ä» æ¾ç¤ºç¬¬ä¸ä¸ªåæ¯å@åé¢çå°åæ¾ç¤ºï¼å ¶ä»æå·æ¿æ¢ */ EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")), /** * é¶è¡å¡å·ï¼ä¿çæå4ä½ï¼å ¶ä»æå·æ¿æ¢ */ BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")), /** * 车çå·ç ï¼å 嫿®é车è¾ãæ°è½æºè½¦è¾ */ CAR_LICENSE(DesensitizedUtil::carLicense); private final Function<String, String> desensitizer; DesensitizedType(Function<String, String> desensitizer) { this.desensitizer = desensitizer; } public Function<String, String> desensitizer() { return desensitizer; } } src/main/java/com/ruoyi/framework/config/SensitiveJsonSerializer.java
¶Ô±ÈÐÂÎļþ @@ -0,0 +1,67 @@ package com.ruoyi.framework.config; import java.io.IOException; import java.util.Objects; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.BeanProperty; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.ser.ContextualSerializer; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.framework.aspectj.lang.annotation.Sensitive; import com.ruoyi.framework.aspectj.lang.enums.DesensitizedType; import com.ruoyi.framework.security.LoginUser; /** * æ°æ®è±æåºååè¿æ»¤ * * @author ruoyi */ public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer { private DesensitizedType desensitizedType; @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { if (desensitization()) { gen.writeString(desensitizedType.desensitizer().apply(value)); } else { gen.writeString(value); } } @Override public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException { Sensitive annotation = property.getAnnotation(Sensitive.class); if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) { this.desensitizedType = annotation.desensitizedType(); return this; } return prov.findValueSerializer(property.getType(), property); } /** * æ¯å¦éè¦è±æå¤ç */ private boolean desensitization() { try { LoginUser securityUser = SecurityUtils.getLoginUser(); // 管çåä¸è±æ return !securityUser.getUser().isAdmin(); } catch (Exception e) { return true; } } }