什么是脱敏?
指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。例如客户的身份证号、手机号等这些都属于客户的隐私信息,都需要对这些数据进行脱敏操作,防止泄漏。
解下来我们实现代码,主要用的是jackson相关包,spring-web中已经集成了,无需添加。
我们新增脱敏注解:
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizationJsonSerializer.class)
public @interface Desensitization {
Class<? extends AbstractDesensitization> value();
}
然后是脱敏序列化:
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;
/**
* 脱敏序列化
*/
public class DesensitizationJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {
private AbstractDesensitization desensitization;
public DesensitizationJsonSerializer(AbstractDesensitization desensitization) {
this.desensitization = desensitization;
}
@Override
public void serialize(String s, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString(desensitization.serialize(s));;
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
JsonSerializer<?> jsonSerializer = null;
if(null == beanProperty) jsonSerializer = serializerProvider.findNullValueSerializer(beanProperty);
if(!Objects.equals(beanProperty.getType().getRawClass(), String.class))
jsonSerializer = serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
if(Objects.equals(beanProperty.getType().getRawClass(), String.class)){
jsonSerializer = setDesensitization(jsonSerializer, beanProperty);
}
return jsonSerializer;
}
/**
* 设置脱敏
* @param beanProperty
* @return
*/
private JsonSerializer<?> setDesensitization(JsonSerializer<?> jsonSerializer, BeanProperty beanProperty) {
Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class);
if (desensitization == null) desensitization = beanProperty.getContextAnnotation(Desensitization.class);
if (desensitization != null) {
//设置脱敏实例
try {
jsonSerializer = new DesensitizationJsonSerializer(desensitization.value().newInstance());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return jsonSerializer;
}
}
脱敏父类实现类:
package com.haileer.dd.dingdingserver.tuomin;
public abstract class AbstractDesensitization {
/**
* 脱敏
* @param value
* @return
*/
public abstract String serialize(String value);
}
然后是自己的需要写子类,例如身份证脱敏子类或者手机号脱敏子类:
public class IdCardDesensitization extends AbstractDesensitization {
@Override
public String serialize(String value) {
return value.replaceAll("(?<=\\w{3})\\w(?=\\w{4})","*");
}
}
public class PhoneDesensitization extends AbstractDesensitization {
@Override
public String serialize(String value) {
return value.replaceAll("(\\d{3})\\d{4}(\\d{4})","$1****$2");
}
}
然后脱敏实现:
看结果:
脱敏成功!