springboot如何做数据脱敏最高效?

在涉及到个人信息的业务接口中,数据脱敏是很重要的,那么如果最高效,最方便的做数据脱敏呢? 

一般对便捷有要求的我们都可以通过注解配合spring Aop 或者相应的过滤器去实现

在项目中对json的处理我一般比较喜欢用阿里的fastjson , 我们只需要引入fastjson的依赖


<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.54</version>
</dependency>

然后就是去继承webmvcconfiguer 


@Component
public class MyWebMvcConfigurationSupport extends WebMvcConfigurationSupport {
 
    
            
    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
 
        /// -> JSON消息转换器(采用阿里的fastjson)
        // 创建一个转换器对象;
        FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
 
        // 个性化配置转换特性
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        // 配置:要格式化返回的json数据
        fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
        // 配置:把空的值的key也返回
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteMapNullValue);
        // 字段如果为null,输出为false,而非null
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullBooleanAsFalse);
        // 数值字段如果为null,输出为0,而非null
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullNumberAsZero);
        // List字段如果为null,输出为[],而非null;
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullListAsEmpty);
        // 字符类型字段如果为null,输出为"",而非null
        fastJsonConfig.setSerializerFeatures(SerializerFeature.WriteNullStringAsEmpty);
        fastJsonHttpMessageConverter.setFastJsonConfig(fastJsonConfig);
 

 
        // 将convert添加到converters当中.
        converters.add(1,fastJsonHttpMessageConverter);
       
   
    }
}

这里要注意的是   因为我在mvc中组合了很多消息转换器 它们被房放在list集合中,当被返回值处理器调用的时候会按照顺序从第一个 消息转换器开始尝试,如果你没有将web starter中自引入的Jackson排除掉,那么第一要将fastjson的转换器添加到集合的前面,不然会失效。

将fastjson设为转换器后,我们写一个注解

@Documented
@Target(value = {ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface Desensitive {
	/**
	 * 数据脱敏策略(类型),默认无
	 */
	DesensitizedType value() default DesensitizedType.NONE;
}
public enum DesensitizedType {
    /**
     * 用户名
     */
    USERNAME(s -> s.replaceAll("\\S*(\\S)", "***$1")),
    /**
     * 身份证
     */
    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;

    SensitiveEnum(Function<String, String> desensitizer) {
        this.desensitizer = desensitizer;
    }

    public Function<String, String> desensitizer() {
        return desensitizer;
    }
}

然后写对应的过滤器逻辑  这个过滤器是fastjson在写入写入每个字段之前都会调用的过滤器 

 object 就是你要转为json的对象 name 就是当前字段的名称 value就是当前字段的值 

如果是Jackson的话也有相应的过滤器

因为我们的枚举类是一个 函数式接口 因此我们在过滤器中判断如果加了当前注解,那么就得到当前注解枚举对应的 apply方法 将原有的value传进去进行脱敏即可   这里的脱敏可以自己实现也可以使用hutool中的工具类   

public class DesensitizeValueFilter implements ValueFilter {
	@Override
	public Object process(Object object, String name, Object value) {
		try {
			Field field = object.getClass().getDeclaredField(name);
			Desensitive desensitive = field.getAnnotation(Desensitive.class);
			if (desensitive == null) {
				return value;
			}
	
			if (!(value instanceof String valueStr) || ((String) value).length() == 0) {
				return value;
			}
			String value= desensitive.value().apply(value);
			   return value

			}
		} catch (NoSuchFieldException e) {
			return value;
		}
		
}

最后别忘记了将写好的 ValueFilter 加入到 前面 fastjson的 config中去 

这样 所有加了相应注解的字段便完成了脱敏   下次哪个字段想脱敏直接加相应的注解即可 是不是很方便呢  

  • 19
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值