前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >我用注解优雅的实现了数据的脱敏

我用注解优雅的实现了数据的脱敏

作者头像
Lvshen
发布2022-05-05 19:24:04
1.9K1
发布2022-05-05 19:24:04
举报

1使用场景

你平时肯定做过这样的需求。要求展示用户的手机号,但是不能完全展示,需要在中间给手机号打码,如下图:

我们将关键数据做了适当隐藏,这样就叫数据脱敏。

2数据脱敏

数据脱敏又称数据去隐私化数据变形,是在给定的规则、策略下对敏感数据进行变换、修改的技术机制,能够在很大程度上解决敏感数据在非可信环境中使用的问题。根据数据保护规范和脱敏策略.对业务数据中的敏感信息实施自动变形.实现对敏感信息的隐藏。

我们来看看具体需求,现在要求对以下数据的电话号码和身份证号码适当隐藏处理:

要求脱敏处理后的效果为:

如上图,我们将手机号与身份证号做了适当的隐藏。

我们常规的做法是先获取到userInfo,然后获取mobileidCard,再将mobileidCard做相应的脱敏处理,最后再setuserInfo中。

但这里有个问题这里我们调用了getUserInfo()后,采用了大量的代码去专门处理脱敏数据,而实际上我们只是要获取userInfo的信息而已,为此我决定采用注解的形式,将数据进行数据脱敏即可。

3代码实现

我们先列出数据脱敏的类型

上面为我们需要脱敏的数据枚举。

然后我们根据不同的枚举类型调用各自的脱敏方法

我们还要编写一个处理序列化的类

我们在SensitiveDataSerialize类中重写了serialize(),里面调用了我们之前的jsonHandler(s, jsonGenerator)数据脱敏的方法,这个方法根据不同的枚举类型实现对应的数据脱敏。

然后我们还要重写createContextual()方法,这里面实现的功能就是扫描脱敏注解然后实现各自的数据脱敏。

接下来我们定义脱敏注解。

这个value()是我们传入的类型枚举。

我们来看看具体的脱敏方法,脱敏方法我主要写在这个SensitiveInfoUtils工具类中。这里我们来看一个手机号脱敏方法。

简单来说,就是字符串的截取和替换。

我们在实体类中标上数据脱敏的注解

根据业务需求,我们对手机号和身份证进行数据脱敏。

最后我们在Controller层写一个接口:

启动工程运行接口,获取如开头的结果:

4关于代码封装性思考

前面我们写的jsonHandler()方法是根据类型枚举调用对应的脱敏方法

代码语言:javascript
复制
switch (this.type) {
    case CHINESE_NAME: {
        jsonGenerator.writeString(SensitiveInfoUtils.chineseName(s));
        break;
    }
    case ID_CARD: {
        jsonGenerator.writeString(SensitiveInfoUtils.idCardNum(s));
        break;
    }
    case FIXED_PHONE: {
        jsonGenerator.writeString(SensitiveInfoUtils.fixedPhone(s));
        break;
    }
    case MOBILE_PHONE: {
        jsonGenerator.writeString(SensitiveInfoUtils.mobilePhone(s));
        break;
    }
    case ADDRESS: {
        jsonGenerator.writeString(SensitiveInfoUtils.address(s, 4));
        break;
    }
    case EMAIL: {
        jsonGenerator.writeString(SensitiveInfoUtils.email(s));
        break;
    }
    case BANK_CARD: {
        jsonGenerator.writeString(SensitiveInfoUtils.bankCard(s));
        break;
    }
}

但是我们如果要增加脱敏类型,比如增加学校SCHOOL,那么这个方法就要增加

代码语言:javascript
复制
...
    case SCHOOL: {
        jsonGenerator.writeString(SensitiveInfoUtils.school(s));
        break;
    }

如果再增加其他类型,那么这里就要增加其他类型的代码,这个方法就需要修改,这样就破坏了代码的封装性。因此我决定将其改造成策略模式。

我们来看看目录,这里每个类型对应一个策略类,首先我们来看策略接口:

代码语言:javascript
复制
public interface SensitiveStrategy {

    SensitiveType getSensitiveType();

    String maskingData(String str);
}

我们定义了两个方法,getSensitiveType()是获取对应枚举类型的方法,maskingData(String str)是实现数据脱敏的方法。因为每个实现的策略类大同小异,这里我们看一个策略类,以MobilePhoneStrategy为例。我们来看看代码:

代码语言:javascript
复制
@Component
public class MobilePhoneStrategy implements SensitiveStrategy {

    @Override
    public SensitiveType getSensitiveType() {
        return SensitiveType.MOBILE_PHONE;
    }

    @Override
    public String maskingData(String str) {
        return SensitiveInfoUtils.mobilePhone(str);
    }
}

代码中我们返回了对应的手机类型枚举,和调用了对应的手机号脱敏方法。

然后我们写一个service类:

代码语言:javascript
复制
@Service
public class SensitiveStrategyService {
    Map<SensitiveType, SensitiveStrategy> map = Maps.newHashMap();

    public SensitiveStrategyService(List<SensitiveStrategy> sensitiveStrategyList) {
        sensitiveStrategyList.forEach(sensitiveStrategy -> map.put(sensitiveStrategy.getSensitiveType(), sensitiveStrategy));
    }

    public String generatorSensitive(SensitiveType typeEnum, String str) {
        SensitiveStrategy sensitiveStrategy = map.get(typeEnum);
        if (sensitiveStrategy != null) {
            return sensitiveStrategy.maskingData(str);
        }
        return StringUtils.EMPTY;
    }

}

这里我们用map存入枚举类型和对应的策略类,map数据如下:

之后我们在serialize()方法中调用:

这我们通过SpringContextHolder.getBean()获取容器中的sensitiveStrategyService实例,然后就是调用方法。

我们同样获取了想要的结果。

使用策略模式,我们需要增加类型时,只需要新增一个策略类,在里面重写好对应的方法,其他地方都不需要修改。

以上就是今天的全部内容了

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Lvshen的技术小屋 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1使用场景
  • 2数据脱敏
  • 3代码实现
  • 4关于代码封装性思考
相关产品与服务
数据脱敏
数据脱敏(Data Masking,DMask)是一款敏感数据脱敏与水印标记工具,可对数据系统中的敏感信息进行脱敏处理并在泄漏时提供追溯依据,为企业数据共享、迁移、分发提供安全保护措施。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档