parent
86ca404dbf
commit
1140a6c333
@ -0,0 +1,24 @@ |
|||||||
|
package com.ruoyi.common.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.common.config.serializer.SensitiveJsonSerializer; |
||||||
|
import com.ruoyi.common.enums.DesensitizedType; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据脱敏注解 |
||||||
|
* |
||||||
|
* @author ruoyi |
||||||
|
*/ |
||||||
|
@Retention(RetentionPolicy.RUNTIME) |
||||||
|
@Target(ElementType.FIELD) |
||||||
|
@JacksonAnnotationsInside |
||||||
|
@JsonSerialize(using = SensitiveJsonSerializer.class) |
||||||
|
public @interface Sensitive |
||||||
|
{ |
||||||
|
DesensitizedType desensitizedType(); |
||||||
|
} |
||||||
@ -0,0 +1,67 @@ |
|||||||
|
package com.ruoyi.common.config.serializer; |
||||||
|
|
||||||
|
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.annotation.Sensitive; |
||||||
|
import com.ruoyi.common.core.domain.model.LoginUser; |
||||||
|
import com.ruoyi.common.enums.DesensitizedType; |
||||||
|
import com.ruoyi.common.utils.SecurityUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据脱敏序列化过滤 |
||||||
|
* |
||||||
|
* @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; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,59 @@ |
|||||||
|
package com.ruoyi.common.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; |
||||||
|
} |
||||||
|
} |
||||||
@ -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; |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue