feature: 增加脱敏功能

This commit is contained in:
laker
2024-04-28 16:20:43 +08:00
parent cb73d05e4d
commit 14de447107
8 changed files with 173 additions and 9 deletions

View File

@@ -34,7 +34,7 @@
<!-- 3.maven打包跳过测试 -->
<skipTests>true</skipTests>
<!-- 其他依赖组件版本 -->
<hutool.version>5.5.2</hutool.version>
<hutool.version>5.8.25</hutool.version>
</properties>
<dependencies>

View File

@@ -0,0 +1,32 @@
package com.laker.admin.framework.ext.desensitization;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@JacksonAnnotationsInside //主要用于标记其他自定义注解,这意味着你可以在一个 Jackson 注解内部使用其他自定义注解,以组合各种注解来实现更复杂的序列化和反序列化逻辑。
@JsonSerialize(using = SensitiveInfoSerializer.class) // 用于指定在序列化时应该使用哪个自定义序列化器类
@Retention(RetentionPolicy.RUNTIME) // 运行时生效。
@Target(ElementType.FIELD) // 用在字段上。
public @interface Desensitization {
/**
* 脱敏数据类型在CUSTOMIZE_RULE的时候startInclude和endExclude生效
*/
DesensitizationTypeEnum type() default DesensitizationTypeEnum.DEFAULT;
/**
* 脱敏开始位置(包含)
*/
int startInclude() default 0;
/**
* 脱敏结束位置(不包含)
*/
int endExclude() default 0;
}

View File

@@ -0,0 +1,31 @@
package com.laker.admin.framework.ext.desensitization;
/**
* 脱敏策略枚举
*/
public enum DesensitizationTypeEnum {
//自定义
CUSTOMIZE_RULE,
// 默认的
DEFAULT,
//用户id
USER_ID,
//中文名
CHINESE_NAME,
//身份证号
ID_CARD,
//座机号
FIXED_PHONE,
//手机号
MOBILE_PHONE,
//地址
ADDRESS,
//电子邮件
EMAIL,
//密码
PASSWORD,
//中国大陆车牌,包含普通车辆、新能源车辆
CAR_LICENSE,
//银行卡
BANK_CARD
}

View File

@@ -0,0 +1,94 @@
package com.laker.admin.framework.ext.desensitization;
import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import java.io.IOException;
/**
* 数据脱敏序列化器
*/
public class SensitiveInfoSerializer extends JsonSerializer<String> implements ContextualSerializer {
private boolean useMasking = false;
private DesensitizationTypeEnum type;
private int startInclude;
private int endExclude;
@Override
public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializers) throws IOException {
if (useMasking && value != null) {
switch (type) {
// 自定义类型脱敏
case CUSTOMIZE_RULE:
jsonGenerator.writeString(StrUtil.hide(value, startInclude, endExclude));
break;
// userId脱敏
case USER_ID:
jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId()));
break;
// 中文姓名脱敏
case CHINESE_NAME:
jsonGenerator.writeString(DesensitizedUtil.chineseName(value));
break;
// 身份证脱敏
case ID_CARD:
jsonGenerator.writeString(DesensitizedUtil.idCardNum(value, 1, 2));
break;
// 固定电话脱敏
case FIXED_PHONE:
jsonGenerator.writeString(DesensitizedUtil.fixedPhone(value));
break;
// 手机号脱敏
case MOBILE_PHONE:
jsonGenerator.writeString(DesensitizedUtil.mobilePhone(value));
break;
// 地址脱敏
case ADDRESS:
jsonGenerator.writeString(DesensitizedUtil.address(value, 8));
break;
// 邮箱脱敏
case EMAIL:
jsonGenerator.writeString(DesensitizedUtil.email(value));
break;
// 密码脱敏
case PASSWORD:
jsonGenerator.writeString(DesensitizedUtil.password(value));
break;
// 中国车牌脱敏
case CAR_LICENSE:
jsonGenerator.writeString(DesensitizedUtil.carLicense(value));
break;
// 银行卡脱敏
case BANK_CARD:
jsonGenerator.writeString(DesensitizedUtil.bankCard(value));
break;
case DEFAULT:
jsonGenerator.writeString(value);
default:
jsonGenerator.writeString(value);
}
} else {
jsonGenerator.writeObject(value);
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
if (property != null) {
Desensitization desensitization = property.getAnnotation(Desensitization.class);
if (desensitization != null) {
this.type = desensitization.type();
this.startInclude = desensitization.startInclude();
this.endExclude = desensitization.endExclude();
useMasking = true;
}
}
return this;
}
}

View File

@@ -45,14 +45,14 @@ public class PageVO implements Serializable {
page.setSize(size);
if (StrUtil.isNotBlank(orderBy)) {
List<OrderItem> orders = new ArrayList<>();
String[] orderItems = StrUtil.split(orderBy, ",");
List<String> orderItems = StrUtil.split(orderBy, ",");
for (String orderItemStr : orderItems) {
String[] orderAndSort = StrUtil.split(orderItemStr, " ");
List<String> orderAndSort = StrUtil.split(orderItemStr, " ");
if (CollUtil.size(orderAndSort) != 2) {
continue;
}
String order = orderAndSort[0];
String sort = orderAndSort[1];
String order = orderAndSort.get(0);
String sort = orderAndSort.get(1);
orders.add(new OrderItem(order, StrUtil.equalsIgnoreCase("ASC", sort)));
}
page.setOrders(orders);

View File

@@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.laker.admin.framework.ext.desensitization.Desensitization;
import com.laker.admin.framework.ext.desensitization.DesensitizationTypeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -30,6 +32,7 @@ public class SysUser implements Serializable {
private String userName;
@Desensitization(type = DesensitizationTypeEnum.PASSWORD)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
@@ -42,10 +45,11 @@ public class SysUser implements Serializable {
private String deptName;
private Integer sex;
@Desensitization(type = DesensitizationTypeEnum.MOBILE_PHONE)
private String phone;
private Integer enable;
@Desensitization(type = DesensitizationTypeEnum.EMAIL)
private String email;
private String avatar;

View File

@@ -1,6 +1,8 @@
package com.laker.admin.module.sys.pojo;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.laker.admin.framework.ext.desensitization.Desensitization;
import com.laker.admin.framework.ext.desensitization.DesensitizationTypeEnum;
import lombok.Data;
import javax.validation.constraints.NotBlank;
@@ -16,6 +18,7 @@ public class LoginDto {
/**
* 因为密码比较重要,故仅用于反序列化
*/
@Desensitization(type = DesensitizationTypeEnum.PASSWORD)
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
@NotBlank(message = "验证码不能为空")

View File

@@ -88,9 +88,9 @@ public class CodeGenerator {
public void initMap() {
Map<String, Object> map = new HashMap<>();
String table = tables[0];
String[] split = StrUtil.split(table, "_");
map.put("easyModule", split[0]);
map.put("easyMain", split[1]);
List<String> split = StrUtil.split(table, "_");
map.put("easyModule", split.get(0));
map.put("easyMain", split.get(1));
this.setMap(map);
}
};