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;
}
User

 

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;
    }
}

 

posted @ 2021-06-10 11:36  wf.zhang  阅读(3097)  评论(0编辑  收藏  举报