JSON脫敏插件(Springboot2)

背景

最近項目涉及到用戶隱私敏感信息(比如:身份證,手機號),防止敏感信息泄露,進行了脫敏處理。

方案調研

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);
    }

}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容