接口数据脱敏

背景介绍

项目业务(银行、医院、购物平台等)经常涉及到个人手机号、身份证号等敏感信息,针对这些信息设计对应接口时,通常接口返回值中的敏感数据需要进行脱敏操作,记录三种实现接口数据脱敏方法

方案

MyBatis

整合MyBatis插件,在查询的时候针对特定的字段进行脱敏

  1. mybatis-plus的数据脱敏使用
  2. Mybatis插件+注解实现数据脱敏

Jackson

在序列化阶段对特定字段进行脱敏

  1. 自定义一个Jackson注解
    一旦属性被标注,则进行对应的脱敏

    1
    2
    3
    4
    5
    6
    7
    8
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    @JacksonAnnotationsInside
    @JsonSerialize(using=SensitiveJsonSerializer.class)
    public @interface Sensitive{
    // 脱敏策略
    SensitiveStrategy strategy();
    }
  2. 定制脱敏策略

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    public enum SensitiveStrategy{
    /*
    * 用户名
    */
    USERNAME(s->s.replaceAll("(\\S)\\S(\\S)","($1*$2)")),
    /*
    * 身份证
    */
    ID_CARD(s->s.replaceAll("(\\d{4}\\d{10}(\\w{4})","$1****$2")),
    /*
    *手机号
    */
    PHONE(s->s.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2")),
    /*
    *地址
    */
    ADDRESS(s->s.replaceA1l("(\\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;
    }
    }
  3. 定制JSON序列化实现

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    /**
    * 序列化注解自定义实现
    * JsonSerializer<String>:指定String 类型,serialize()方法用于将修改后的数据载入
    */
    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);

    }
    }
  4. 定制需要脱敏对象类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @Data
    public class person{
    /**
    *真实姓名
    */
    @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;
    }

  5. 接口测试

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @RestController
    public class TestController{
    @GetMapping("/test")
    public Person test(){
    Person user = new Person();
    user.setRealName("李小明");
    user.setPhoneNumber("12345678901");
    user.setAddress("北京市");
    user.setIdCard("4333333333334334333");
    return user;
    }
    }

Sharding Sphere

ShardingSphere-ShardingJdbc 数据脱敏

shardingsphere官方文档

总结

目前仅作小记,未来开发涉及到后,做更进一步的分析理解


接口数据脱敏
http://oowatermelon.github.io/OoWaterMelonS/2022/12/03/接口数据脱敏/
作者
OoWaterMelonS Shao
发布于
2022年12月3日
许可协议