java注解方式实现数据脱敏
使用注解方式结合Jackson实现数据脱敏
转自 https://mp.weixin.qq.com/s/GmELzTYIwYAIpTVRyCh9mw
最后效果
思路; 1.自定义脱敏注解 2.自定义脱敏逻辑 3.具体字段脱敏策略
1.自定义脱敏注解 标注在实体类 具体 需要脱敏 字段上
其中用到Jackson的两个注解, 并标明使用我们自定义脱敏策略即序列化后脱敏
@Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using = SensitiveJsonSerializer.class) public @interface Sensitive { SensitiveStrategy strategy(); }
标注实体类字段上
@TableName(value ="t_user") @Data public class User implements Serializable { @TableId(type = IdType.AUTO) private Integer id; /** * 真实姓名 */ @Sensitive(strategy = SensitiveStrategy.USERNAME) private String realName; /** * 地址 */ @Sensitive(strategy = SensitiveStrategy.ADDRESS) private String address; /** * 电话号码 */ @Sensitive(strategy = SensitiveStrategy.PHONE) private String phoneNumber; /** * 身份证号码 */ @Sensitive(strategy = SensitiveStrategy.ID_CARD) private String idCard; @TableField(exist = false) private static final long serialVersionUID = 1L; }
2.自定义脱敏逻辑 数据json化才实现脱敏
数据库查询的数据可以继续进行业务逻辑
返回给前端json数据时才进行脱敏
借助Jackson类和接口实现序列化才脱敏
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer { private SensitiveStrategy strategy; @Override public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeString(strategy.desensitizer().apply(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.strategy = annotation.strategy(); return this; } return prov.findValueSerializer(property.getType(), property); } }
3.具体字段脱敏策略 注解时使用对应字段的策略
public enum SensitiveStrategy { /** * Username sensitive strategy. */ USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")), /** * Id card sensitive type. */ ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")), /** * Phone sensitive type. */ PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")), /** * Address sensitive type. */ ADDRESS(s -> s.replaceAll("(\\S{3})\\S{2}(\\S*)\\S{2}", "$1****$2****")); private final Function<String, String> desensitizer; SensitiveStrategy(Function<String, String> desensitizer) { this.desensitizer = desensitizer; } public Function<String, String> desensitizer() { return desensitizer; } }
古人学问无遗力,少壮工夫老始成。
纸上得来终觉浅,绝知此事要躬行。