SpringBoot进阶教程(七十五)数据脱敏

无论对于什么业务来说,用户数据信息的安全性无疑都是非常重要的。尤其是在数字经济大火背景下,数据的安全性就显得更加重要。数据脱敏可以分为两个部分,一个是DB层面,防止DB数据泄露,暴露用户信息;一个是接口层面,有些UI展示需要数据脱敏,防止用户信息被人刷走了。

v需求背景

DB层面的脱敏今天先不讲,今天先讲讲依赖于注解的接口层面的数据脱敏,接口层面的脱敏可能最原始和简单的方法就是在每个controller输出数据时,硬性处理。但是这么做的方案,如果后续脱敏规则改了,那需要改的地方就太多了,而且很容易有遗漏的地方,造成全站脱敏规则不统一的情况。所以我们建议的是用注解的方式,可插拔性更好,随时可以更改规则,更加的灵活。

我们今天接到的需求是这样的:

SpringBoot进阶教程(七十五)数据脱敏

页面或者接口层面的脱敏,大多也是围绕用户手机号啊、真实姓名或者地址等等展开的。

v架构设计

2.1 脱敏字段枚举:SensitivityEnum

这里定义一个敏感字段的枚举,并设定各个字段的脱敏策略。

/**  * @Author tou tou  * @Date 2023/1/15  * @Des 脱敏类型及策略,不同的字段类型适配不同的策略  */ public enum SensitivityEnum {     /**      * 用户名      */     USERNAME(s -> s.replaceAll("\S*(\S)", "***$1")),     /**      * 身份证      */     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.replaceAll("(\S{3})\S{2}(\S*)\S{2}", "$1****$2****"));       private final Function<String, String> desensitizer;      SensitivityEnum(Function<String, String> desensitizer) {         this.desensitizer = desensitizer;     }      public Function<String, String> desensitizer() {         return desensitizer;     } }

2.2 创建自定义隐私注解:Sensitivity

都说了,我们使用的是注解的方式脱敏,所以是需要声明一个脱敏注解的,需要用到的地方,按需声明注解即可。非常方便。

/**  * @Author tou tou  * @Date 2023/1/15  * @Des  */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) @JacksonAnnotationsInside @JsonSerialize(using = SensitivitySerializer.class) public @interface Sensitivity {     SensitivityEnum strategy(); }

2.3 创建序列化类:SensitivitySerializer
/**  * @Author tou tou  * @Date 2023/1/15  * @Des  */ public class SensitivitySerializer extends JsonSerializer<String> implements ContextualSerializer {     private SensitivityEnum sensitivityEnum;      @Override     public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {         gen.writeString(sensitivityEnum.desensitizer().apply(value));     }      @Override     public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {          Sensitivity annotation = property.getAnnotation(Sensitivity.class);         if (Objects.nonNull(annotation)&&Objects.equals(String.class, property.getType().getRawClass())) {             this.sensitivityEnum = annotation.strategy();             return this;         }          return prov.findValueSerializer(property.getType(), property);     } }

2.4 使用了@Sensitivity注解的实体类
public class UserAccountVO {     private Integer id;      @Sensitivity(strategy = SensitivityEnum.USERNAME)     private String username;      private Integer age;      @Sensitivity(strategy = SensitivityEnum.PHONE)     private String tel;      private String email;      private String account; }

2.5 插入mysql测试数据
create table useraccount ( id INT(11), username NVARCHAR(25), age INT(11), phone bigint, email VARCHAR(80), account VARCHAR(20), pwd VARCHAR(20) );  select * from useraccount; insert into useraccount values(1,'张老三', 22, 13555551111,'13555551111@126.com','z13555551111', '13555551111');

2.6 测试接口
/**  * @author toutou  * @date by 2019/07  */ @RestController public class UserController {      @Autowired     UserAccountService userAccountService;          @GetMapping("/user/getuser")     public Result getUserAccountById(@RequestParam("uid") int id){         UserAccountVO user = userAccountService.getUserAccountById(id);         if(user != null){             return Result.setSuccessResult(user);         }else{             return Result.setErrorResult(404, "用户不存在");         }     } }

v运行效果

SpringBoot进阶教程(七十五)数据脱敏

v源码地址

https://github.com/toutouge/javademosecond/tree/master/hellolearn

作  者:请叫我头头哥
出  处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

发表评论

评论已关闭。

相关文章