场景
SpringBoot中整合Sharding Sphere实现数据加解密/数据脱敏/数据库密文,查询明文:
SpringBoot中整合Sharding Sphere实现数据加解密/数据脱敏/数据库密文,查询明文_霸道流氓气质的博客-CSDN博客
上面讲的是数据库中存储密文,查询时使用明文的脱敏方式,如果是需要数据库中存储
明文,而在查询时返回处理后的数据,比如身份证号、手机号等敏感数据,可以通过如下方式。
注:
博客:
霸道流氓气质的博客_CSDN博客-C#,架构之路,SpringBoot领域博主
实现
1、自定义Jackson注解
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive {
//脱敏策略
SensitiveStrategy strategy();
}
2、指定脱敏策略,这个规则根据业务具体需求去制定,下面只做演示
import java.util.function.Function;
/**
* 脱敏策略,枚举类,针对不同的数据定制特定的策略
*/
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.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;
}
}
3、定制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 java.io.IOException;
import java.util.Objects;
/**
* 序列化注解自定义实现
* 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、新增User类,并对需要脱敏的字段添加注解,并指定脱敏策略
import com.badao.demo.sensitive.Sensitive;
import com.badao.demo.sensitive.SensitiveStrategy;
import lombok.Data;
import java.io.Serializable;
@Data
public class User implements Serializable {
private static final long serialVersionUID = -5514139686858156155L;
private Integer id;
private Integer userId;
@Sensitive(strategy = SensitiveStrategy.USERNAME)
private String name;
private Integer age;
}
5、编写controller进行测试
@RequestMapping("user")
@RestController
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("save")
public String save() {
User user = new User();
user.setUserId(new Random().nextInt( 1000 ) + 1);
user.setName("badao"+user.getUserId());
user.setAge(new Random().nextInt( 80 ) + 1);
userService.insert(user);
return "save success";
}
@RequestMapping("select")
public User select() {
List<User> all = userService.findAll();
return all.size()>0?all.get(0):new User();
}
}
测试效果