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

v需求背景

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

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

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

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运行效果

v源码地址

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

作  者:请叫我头头哥


出  处:http://www.cnblogs.com/toutou/


关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!


版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。


特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信


声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!

#comment_body_3242240 { display: none }

SpringBoot进阶教程(七十五)数据脱敏的更多相关文章

  1. SpringBoot进阶教程(七十四)整合ELK

    在上一篇文章<SpringBoot进阶教程(七十三)整合elasticsearch >,已经详细介绍了关于elasticsearch的安装与使用,现在主要来看看关于ELK的定义.安装及使用 ...

  2. SpringBoot进阶教程(六十五)自定义注解

    在上一篇文章<SpringBoot进阶教程(六十四)注解大全>中介绍了springboot的常用注解,springboot提供的注解非常的多,这些注解简化了我们的很多操作.今天主要介绍介绍 ...

  3. SpringBoot进阶教程(七十)SkyWalking

    流行的APM(Application Performance Management工具有很多,比如Cat.Zipkin.Pinpoint.SkyWalking.优秀的监控工具还有很多,其它比如还有za ...

  4. SpringBoot进阶教程(二十五)整合Redis之@Cacheable、@CachePut、@CacheEvict的应用

    在上一篇文章(<SpringBoot(二十四)整合Redis>)中,已经实现了Spring Boot对Redis的整合,既然已经讲到Cache了,今天就介绍介绍缓存注解.各家互联网产品现在 ...

  5. SpringBoot进阶教程(六十四)注解大全

    在Spring1.x时代,还没出现注解,需要大量xml配置文件并在内部编写大量bean标签.Java5推出新特性annotation,为spring的更新奠定了基础.从Spring 2.X开始spri ...

  6. SpringBoot进阶教程(二十九)整合Redis 发布订阅

    SUBSCRIBE, UNSUBSCRIBE 和 PUBLISH 实现了 发布/订阅消息范例,发送者 (publishers) 不用编程就可以向特定的接受者发送消息 (subscribers). Ra ...

  7. SpringBoot进阶教程(六十八)Sentinel实现限流降级

    前面两篇文章nginx限流配置和SpringBoot进阶教程(六十七)RateLimiter限流,我们介绍了如何使用nginx和RateLimiter限流,这篇文章介绍另外一种限流方式---Senti ...

  8. SpringBoot进阶教程(七十一)详解Prometheus+Grafana

    随着容器技术的迅速发展,Kubernetes已然成为大家追捧的容器集群管理系统.Prometheus作为生态圈Cloud Native Computing Foundation(简称:CNCF)中的重 ...

  9. SpringBoot进阶教程(六十)intellij idea project下建多个module搭建架构(上)

    在 IntelliJ IDEA 中,没有类似于 Eclipse 工作空间(Workspace)的概念,而是提出了Project和Module这两个概念.多module有一个父maven工程,多个子工程 ...

  10. SpringBoot进阶教程(二十六)整合Redis之共享Session

    集群现在越来越常见,当我们项目搭建了集群,就会产生session共享问题.因为session是保存在服务器上面的.那么解决这一问题,大致有三个方案,1.通过nginx的负载均衡其中一种ip绑定来实现( ...

随机推荐

  1. 5.26 学习SSH

    1.ssh客户端是一种使用Secure Shell协议 连接到运行了ssh服务端的远程服务器上 ssh是比较可靠的,专为远程登录会话和其他网络服务提供安全性的协议 2.

  2. jmeter中使用csv文件时设置编码

    1.新建XLS文件,另存为CSV格式文件 2.在jmeter中可以尝试将编码设置成GB2312,或者utf-8

  3. white album句子

    1.不论是真心的笑,还是真心的生气,我都做不到.我只是个胆小的骗子.

  4. 【项目记录】2:python3 使用MySQL 出现RuntimeError: 'cryptography' package is required for sha256_password or caching_sha2_password auth methods 报错

    报错是因为缺少了一个库 cryptography  导入了就好了. ps:如果是本机,输入IP会报错,直接使用localhost可连接数据库

  5. vue上传证书

    //队伍证书上传 getFile() { var that = this; // //1 创建formData let formData = new FormData(); // //2 添加数据,k ...

  6. pandas(随时更新)

    pandas处理一个表中的一列数据被另一个表中的另一列数据替换: df1=pd.DataFrame({'id':[1,2,3],'name':['Andy1','Jacky1','Bruce1']}) ...

  7. FCC 中级算法题 Binary Agents

    Binary Agents 传入二进制字符串,翻译成英语句子并返回. 二进制字符串是以空格分隔的. String.charCodeAt() String.fromCharCode() 思路: (1)把 ...

  8. tensorflow的断点续训

    tensorflow的断点续训 2019-09-07 顾名思义,断点续训的意思是因为某些原因模型还没有训练完成就被中断,下一次训练可以在上一次训练的基础上继续训练而不用从头开始:这种方式对于你那些训练 ...

  9. matlab/simulink中的执行顺序问题

    关于在simulink中开发一些硬件环境模型,有时候会碰到一些模块的执行先后顺序问题.比如说在一个通过UDP发送指令命令给客户端,要求发送的指令有先后的时间顺序,只有在前一条命令发送完以后,才可以进行 ...

  10. MySql5.7基础配置

    MySql5.7基础配置 [client] #设置mysql客户端的字符集 default-character-set=utf8 [mysqld] #设置mysql端口为3306 port = 330 ...