diff --git a/pom.xml b/pom.xml index d547271..2f6d76f 100644 --- a/pom.xml +++ b/pom.xml @@ -34,7 +34,7 @@ true - 5.5.2 + 5.8.25 diff --git a/src/main/java/com/laker/admin/framework/ext/desensitization/Desensitization.java b/src/main/java/com/laker/admin/framework/ext/desensitization/Desensitization.java new file mode 100644 index 0000000..ae9f0c0 --- /dev/null +++ b/src/main/java/com/laker/admin/framework/ext/desensitization/Desensitization.java @@ -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; + +} \ No newline at end of file diff --git a/src/main/java/com/laker/admin/framework/ext/desensitization/DesensitizationTypeEnum.java b/src/main/java/com/laker/admin/framework/ext/desensitization/DesensitizationTypeEnum.java new file mode 100644 index 0000000..a65b0a1 --- /dev/null +++ b/src/main/java/com/laker/admin/framework/ext/desensitization/DesensitizationTypeEnum.java @@ -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 +} \ No newline at end of file diff --git a/src/main/java/com/laker/admin/framework/ext/desensitization/SensitiveInfoSerializer.java b/src/main/java/com/laker/admin/framework/ext/desensitization/SensitiveInfoSerializer.java new file mode 100644 index 0000000..7a895e9 --- /dev/null +++ b/src/main/java/com/laker/admin/framework/ext/desensitization/SensitiveInfoSerializer.java @@ -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 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; + } +} \ No newline at end of file diff --git a/src/main/java/com/laker/admin/framework/model/PageVO.java b/src/main/java/com/laker/admin/framework/model/PageVO.java index 843c8d3..48bb6e6 100644 --- a/src/main/java/com/laker/admin/framework/model/PageVO.java +++ b/src/main/java/com/laker/admin/framework/model/PageVO.java @@ -45,14 +45,14 @@ public class PageVO implements Serializable { page.setSize(size); if (StrUtil.isNotBlank(orderBy)) { List orders = new ArrayList<>(); - String[] orderItems = StrUtil.split(orderBy, ","); + List orderItems = StrUtil.split(orderBy, ","); for (String orderItemStr : orderItems) { - String[] orderAndSort = StrUtil.split(orderItemStr, " "); + List 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); diff --git a/src/main/java/com/laker/admin/module/sys/entity/SysUser.java b/src/main/java/com/laker/admin/module/sys/entity/SysUser.java index f2e49be..6f04e26 100644 --- a/src/main/java/com/laker/admin/module/sys/entity/SysUser.java +++ b/src/main/java/com/laker/admin/module/sys/entity/SysUser.java @@ -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; diff --git a/src/main/java/com/laker/admin/module/sys/pojo/LoginDto.java b/src/main/java/com/laker/admin/module/sys/pojo/LoginDto.java index 9c02939..645f4e0 100644 --- a/src/main/java/com/laker/admin/module/sys/pojo/LoginDto.java +++ b/src/main/java/com/laker/admin/module/sys/pojo/LoginDto.java @@ -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 = "验证码不能为空") diff --git a/src/test/java/com/laker/admin/CodeGenerator.java b/src/test/java/com/laker/admin/CodeGenerator.java index 484c0e7..de65991 100644 --- a/src/test/java/com/laker/admin/CodeGenerator.java +++ b/src/test/java/com/laker/admin/CodeGenerator.java @@ -88,9 +88,9 @@ public class CodeGenerator { public void initMap() { Map map = new HashMap<>(); String table = tables[0]; - String[] split = StrUtil.split(table, "_"); - map.put("easyModule", split[0]); - map.put("easyMain", split[1]); + List split = StrUtil.split(table, "_"); + map.put("easyModule", split.get(0)); + map.put("easyMain", split.get(1)); this.setMap(map); } };