关键词:
Jackson注解自定义数据脱敏策略
1.前言
有时候,我们返回给前端的数据需要脱敏,避免用户信息被泄漏,就像你点外卖一样,京东或淘宝购物一样,手机号,姓名这些字段是被脱敏后的,在这个大数据时代,用户的数据安全是及其重要的。我们如何对用户统一数据进行脱敏处理呢?如果我们自定义脱敏方式,使用一个工具类,被改字段传递进去,脱敏后返回新的字符串,那这样是很多地方需要手动去编写很多重复的代码,而且不利于维护,比如是单个bean,或者是list的时候还要去遍历一次list。有没有什么方法统一处理呢?我们定义好脱敏规则,只需要在需要脱敏的字段上加上一个注解即可。那当然是可以的
2.脱敏注解
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.springboot.example.desensitizer.handler.SensitiveJsonSerialize;
import com.springboot.example.desensitizer.enums.SensitiveStrategy ;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 脱敏注解
* @author compass
* @date 2022-12-11
* @since 1.0
**/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerialize.class)
public @interface Sensitive
SensitiveStrategy strategy();
3.定义好一套需要脱敏的规则
import java.util.function.Function;
/**
* 对需要特别脱敏的字段指定脱敏规则
* @author compass
* @date 2022-12-11
* @since 1.0
**/
public enum SensitiveStrategy
/**
* 对用户名进行脱敏,基于正则表达式实现
*/
USERNAME(s -> s.replaceAll("(\\\\S)\\\\S(\\\\S*)", "$1*$2")),
/**
* 对身份证进行脱敏
*/
ID_CARD(s -> s.replaceAll("(\\\\d4)\\\\d10(\\\\w4)", "$1****$2")),
/**
* 对电话号码进行脱敏
*/
PHONE(s -> s.replaceAll("(\\\\d3)\\\\d4(\\\\d4)", "$1****$2")),
/**
* 对地址进行脱敏
*/
ADDRESS(s -> s.replaceAll("(\\\\S3)\\\\S2(\\\\S*)\\\\S2", "$1****$2****")),
/**
* 对密码进行脱敏,全部加密即可
*/
PASSWORD(s -> "********");
private final Function<String, String> desensitizeSerializer;
SensitiveStrategy(Function<String, String> desensitizeSerializer)
this.desensitizeSerializer = desensitizeSerializer;
// 用于后续获取脱敏的规则,实现脱敏
public Function<String, String> desensitizeSerializer()
return desensitizeSerializer;
4.自定义JSON序列化
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.springboot.example.desensitizer.annotations.Sensitive;
import com.springboot.example.desensitizer.enums.SensitiveStrategy;
import java.io.IOException;
import java.util.Objects;
/**
* @author compass
* @date 2022-12-11
* @since 1.0
**/
public class SensitiveJsonSerialize extends JsonSerializer<String> implements ContextualSerializer
private SensitiveStrategy strategy;
// 在序列化时进行数据脱敏
@Override
public void serialize(String value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException
jsonGenerator.writeString(strategy.desensitizeSerializer().apply(value));
// 获取注解上的属性
@Override
public JsonSerializer<?> createContextual(SerializerProvider provider, 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 provider.findValueSerializer(property.getType(), property);
5.在实体类上标注对应的脱敏规则
@Data
@ToString
public class Employee
private Long id;
@Sensitive(strategy = SensitiveStrategy.USERNAME)
private String name;
private String email;
@Sensitive(strategy = SensitiveStrategy.ID_CARD)
private String identity;
@Sensitive(strategy = SensitiveStrategy.PASSWORD)
private String password;
@Sensitive(strategy = SensitiveStrategy.PHONE)
private String phone;
private Date birthday;
private String jobNumber;
private Boolean verified;
@Sensitive(strategy = SensitiveStrategy.ADDRESS)
private String address;
5.写一个接口进行测试
@RestController
@RequestMapping("/sensitiveStrategy")
public class SensitiveStrategyController
@GetMapping("/v1/getSensitiveStrategy")
public ResponseResult<Employee> getSensitiveStrategy()
Employee employee = new Employee();
employee.setId(IdUtil.getSnowflakeNextId());
employee.setName("诸葛亮");
employee.setEmail("360369395@qq.com");
employee.setIdentity("522132188881017455X");
employee.setPassword("");
employee.setPhone("17785444960");
employee.setBirthday(new Date());
employee.setJobNumber(IdUtil.getSnowflake().nextIdStr());
employee.setVerified(false);
employee.setAddress("重庆市沙坪坝区大学城中路2-18号");
return ResponseResult.success("请求成功", employee);
调用我们写的测试接口,可以看到,我们的接口都做了脱敏处理
调用我们写的测试接口,可以看到,我们的接口都做了脱敏处理
利用jackson序列化实现数据脱敏
参考技术A先看下jackson的@JsonSerialize注解。@JsonSerialize是jackson提供自定义序列化方法的注解,它有个using属性,指定自定义序列化的执行类;例如:先自定义一个序列化类@JsonSerialize注解的Java类示例我们知道,springMVC是通过jackson... 查看详情
利用jackson序列化实现数据脱敏(代码片段)
...用脱敏符号(*)处理。2.目标在服务端返回数据时,利用Jackson序列化完成数据脱敏,达到对敏感信息脱敏展示。降低重复开发量,提升开发效率形成统一有效的脱敏规则可基于重写默认脱敏实现的desensitize方法,实现可扩展、可... 查看详情
如何优雅的实现数据脱敏(代码片段)
如何优雅的实现数据脱敏Jackson序列化中脱敏自定义脱敏序列化改造脱敏注解使用参考很多时候我们从ORM查询到的数据有其它逻辑要处理,比如根据电话号查询用户信息,你脱敏了就没有办法来处理该逻辑了。所以脱敏这... 查看详情
自定义一个jackson转换注解完成敏感数据的隐藏(代码片段)
...,有些敏感数据的信息隐藏等。本文介绍一个简单的Jackson注解,实现对某些字段的信息隐藏,即将目标对象中的属性,用对应无实际意义的字符替换。定义Jackson注解使 查看详情
java数据脱敏
...行脱敏处理,如:姓名、电话号码、身份证基于jackson,通过自定义注解的方式实现数据脱敏添加依赖spring-web、spring-boot-starter-web已经集成了jackson相关包,不用添加<!--jackson依赖--><dependency><g 查看详情
自定义一个jackson转换注解完成敏感数据的隐藏(代码片段)
...,有些敏感数据的信息隐藏等。本文介绍一个简单的Jackson注解,实现对某些字段的信息隐藏,即将目标对象中的属性,用对应无实际意义的字符替换。定义Jackson注解使用@JacksonAnnotationsInside,定义一个在字... 查看详情
jackson总结:常用注解整合spring自定义jsonserializer(代码片段)
原文地址:https://www.jianshu.com/p/63c5985fb48eJackson作为springMVC默认的MessageConverter(消息序列化工具),经常在项目中使用,如果熟悉Jackson常用的使用方法,特性化机制,就会事半功倍,极大提高前后端数据交互的灵活性。maven依赖&l... 查看详情
一个注解搞定接口返回数据脱敏(代码片段)
...我输”的程序员规范,思来想去,定义数据脱敏注解和数据脱敏逻辑的接口,在返回类上,对需要进行脱敏的属性加上,并指定对应的脱敏策略操作接下来我只需要拦截控制器返回的数据,找到带有脱敏注... 查看详情
java注解的字段脱敏处理(代码片段)
...时候,我们并不希望打印出现,这样,我们使用自己定义注解,来解决这个问题。定义需要脱敏的字段规则。importjava.lang.reflect.Array;importjava.lang.reflect.Field;importjava.lang.reflect.Method;importjava.util.Collection;importj 查看详情
基于注解形式的数据脱敏(代码片段)
数据脱敏注解定义packagecn.com.sensitive.annotations;importjava.lang.annotation.ElementType;importjava.lang.annotation.Retention;importjava.lang.annotation.RetentionPolicy;importjava.lang.annotation.Target;/***敏感方法**@authorzhanghao*@date2019/06/04*/@Retention(RetentionPolicy.RUNTIME)@... 查看详情
求求你别乱脱敏了!mybatis插件+注解轻松实现数据脱敏,soeasy~!(代码片段)
...只需要对ParameterHandler和ResultSetHandler进行切入。定义特定注解,在切入时需要检查字段中是否包含注解来是否加解密加注解定义SensitiveData注解importjava.lang.annotation.*;/***该注解定义在类上*插件通过扫描类对象是否包含这个注解来... 查看详情
自定义注解实例分析(代码片段)
自定义注解Book/*说明:如果一个注解中仅有一个属性数据,那么请将该注解属性的名称定义为value.好处:使用该注解时,可以省略该属性的名称.*///@Target使用的目标位置@Target(ElementType.METHOD,ElementType.FIELD,ElementType.TYPE)//Retention保留//注... 查看详情
java注解--一张图一案例掌握自定义注解(代码片段)
...脱敏、日期格式)在编译时进行格式检查生成帮助文档2.注解相关知识元注解指的是所有注解都基于它们而产生的最基础的注解。2.1.Annotation接口和元注解这张图包含了Annotation接口信息、4个元注 查看详情
使用自定义注解和策略模式去掉if-else(代码片段)
一:写自定义注解packagecom.wing.cloud.base.modular.strategy;importjava.lang.annotation.*;/***<p>*自定义策略注解*</p>**@author:heluwei*@Date:2020/4/2217:52*/@Target(ElementType.TYPE)//作用在类上@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited//子类可以继... 查看详情
java数据定义规则脱敏实现(代码片段)
...eateContextual方法解读createContextual可以获得字段的类型以及注解。createContextual方法只会在第一次序列化字段时调用(因为字段的上下文信息在运行期不会改变),所以不用担心影响性能。二、具体实现代码1.定义注解/**... 查看详情
@jsonserialize(代码片段)
...面限制两位小数点。使用自定义序列化类importcom.fasterxml.jackson.core.JsonGenerator;importcom.fasterxml.jackson.core.< 查看详情
java日志脱敏框架sensitive-新版本0.0.2-深度拷贝,属性为对象和集合的支持
...代码的***性太强。编写起来又特别麻烦。本项目提供基于注解的方式,并且内置了常见的脱敏方式,便于开发。用户也可以基于自己的实际需要,自定义注解。特性基于注解的日志脱敏可以自定义策略实现,策略生效条件常见的... 查看详情
一个注解(优雅)搞定springboot项目中的身份证号手机号等敏感数据脱敏(代码片段)
📞文章简介:一个注解搞定身份证号、手机号等敏感数据脱敏处理💡创作目的:公司中CRM的第一版快封版了,基本功能都落实了。接下来就是预防等保了,我负责的是核心业务客户模块这里自然有很多数... 查看详情