背景
最近項目涉及到用戶隱私敏感信息(比如:身份證,手機號),防止敏感信息泄露,進行了脫敏處理。
方案調研
1. 基于JSON過濾器對響應體脫敏
2. 基于Mybatis攔截器對查詢出數(shù)據進行脫敏
優(yōu)缺點
第2種非常簡單粗暴脫敏,比如:app展示聯(lián)系方式,點擊跳到撥打電話界面,顯示不行了。最終決定采用第1種方案。
實現(xiàn)原理(基于fastjson的ValueFilter)
1. 脫敏函數(shù)接口
public interface Desensitizer extends Function<String, String> {
}
2. 脫敏函數(shù)策略
public enum SensitiveStrategy {
/**
* Username sensitive strategy.
*/
USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
/**
* Id card sensitive type.
*/
ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\w{4})", "$1****$2")),
/**
* Phone sensitive type.
*/
PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
/**
* Address sensitive type.
*/
ADDRESS(s -> s.replaceAll("(\\S{8})\\S{4}(\\S*)\\S{4}", "$1****$2****"));
private final Desensitizer desensitizer;
SensitiveStrategy(Desensitizer desensitizer) {
this.desensitizer = desensitizer;
}
/**
* Gets desensitizer.
*
* @return the desensitizer
*/
public Desensitizer getDesensitizer() {
return desensitizer;
}
}
脫敏注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Sensitive {
SensitiveStrategy strategy();
}
脫敏filter
@Slf4j
public class ValueDesensitizeFilter implements ValueFilter {
@Override
public Object process(Object object, String name, Object value) {
if (null == value || !(value instanceof String) || ((String) value).length() == 0) {
return value;
}
try {
Field[] fields = object.getClass().getDeclaredFields();
List<Field> fieldList = Stream.of(fields).filter(o -> o.getName().equals(name)).collect(Collectors.toList());
if (fieldList == null || fieldList.size() <= 0) {
return value;
}
Field field = fieldList.get(0);
Sensitive sensitive;
if (String.class != field.getType() || (sensitive = field.getAnnotation(Sensitive.class)) == null) {
return value;
}
return sensitive.strategy().getDesensitizer().apply((String) value);
} catch (Exception e) {
log.error("ValueDesensitizeFilter field class:{},name:{},value:{}", object.getClass(), name, value);
return value;
}
}
}
springboot配置
@Configuration
public class WebConfig implements WebMvcConfigurer {
/**
* 配置fastjson為默認JSON轉換
*
* @return
*/
@Bean
public HttpMessageConverters fastJsonHttpMessageConverters() {
// 1.定義一個converters轉換消息的對象
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
// 2.添加fastjson的配置信息,比如: 是否需要格式化返回的json數(shù)據
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.DisableCircularReferenceDetect);
fastJsonConfig.setSerializeFilters(new ValueDesensitizeFilter());//添加自己寫的攔截器
// 3.在converter中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
// 4.將converter賦值給HttpMessageConverter
HttpMessageConverter<?> converter = fastConverter;
// 5.返回HttpMessageConverters對象
return new HttpMessageConverters(converter);
}
}