开发者

Springboot+Hutool自定义注解实现数据脱敏

开发者 https://www.devze.com 2023-11-19 13:41 出处:网络 作者: 掉发的小王
目录一、前言二、什么是数据脱敏三、Hutool简介四、实战整合1. 导入依赖2. 自定义注解3. 支持类型枚举4. 自定义序列化器5. 实体类应用6. 测试五、总结一、前言
目录
  • 一、前言
  • 二、什么是数据脱敏
  • 三、Hutool简介
  • 四、实战整合
    • 1. 导入依赖
    • 2. 自定义注解
    • 3. 支持类型枚举
    • 4. 自定义序列化器
    • 5. 实体类应用
    • 6. 测试
  • 五、总结

    一、前言

    我们在项目中会处理敏感数据(如手机号、身份证号、姓名、地址等)时,通常需要对这些数据进行脱敏,以确保数据隐私和安全。

    我们本次使用 Hutool 库来轻松实现数据脱敏,如果项目中不让使用,可以自己防着hutool来写一些工具类。

    本次使用Springboot整合Hutool来自定义注解实现数据脱敏!

    二、什么是数据脱敏

    数据脱敏(Data Masking) ,也称为数据遮蔽或数据隐藏,是一种 数据保护技术 ,用于处理和存储敏感数据时,以减少或消除数据中的敏感信息,从而保护数据的隐私和安全。数据脱敏的主要目的是在保持数据可用性的同时,减少数据泄露和滥用的风险。

    数据脱敏一般指数据库正常存储,返回前端时进行数据库处理!

    三、Hutool简介

    Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

    Hutool是项目中“util”包友好的替代,它节省了开发人员对项目中公用类和公用工具方法的封装时间,使开发专注于业务,同时可以最大限度的避免封装不完善带来的bug。

    虽然Hutool可能会有一些bug,比起小编写的还是强上不少的,所以选定它来!

    现在最新版为: 5.8.16 ,我们直接使用最新的,bug会少一些,功能会完善一些!

    支持的脱敏规则:

    • 用户id
    • 中文姓名
    • 身份证号
    • 座机号
    • 手机号
    • 地址
    • 电子邮件
    • 密码
    • 中国大陆车牌,包含普通车辆、新能源车辆
    • 银行卡

    四、实战整合

    1. 导入依赖

    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-all</artifactId>
        <version>php;5.8.16</version>
    </dependency>

    2. 自定义注解

    @jsonSerialize(using = SensitiveInfoSerializer.class) 用于指定在序列化时应该使用哪个自定义序列化器类

    需要和下面的注解搭配使用 SensitiveInfoSerializer 我们自定义的序列化器才会生效

    @JacksonAnnotationsInside 主要用于标记其他自定义注解,这意味着你可以在一个 Jackson 注解内部使用其他自定义注解,以组合各种注解来实现更复杂的序列化和反序列化逻辑。

    /**
     * @author wangzhenjun
     * @date 2023/9/11 14:15
     */
    @JacksonAnnotationsInside
    @JsonSerialize(using = SensitiveInfoSerializer.class)
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Desensitization {
        DesensitizationType type() default DesensitizationType.DEFAULT;
        /**
         * 前置不需要打码的长度
         */
        int prefixLen() default 0;
        /**
         * 后置不需要打码的长度
         */
        int suffixLen() default 0;
        /**
         * 遮罩字符
         */
        String maskingChar() default "*";
    }

    3. 支持类型枚举

    /**
     * @author wangzhenjun
     * @date 2023/9/11 14:43
     */
    public enum DesensitizationType {
        // 自定义规则
        CUSTOMIZE_RULE,
        // 默认的
        DEFAULT,
        //用户id
        USER_ID,
        //中文名
        CHINESE_NAME,
        //身份证号
        ID_CARD,
        //座机号
        FIXED_PHONE,
        //手机号
        MOBILE_PHONE,
        //地址
        ADDRESS,
        //电子邮件
        EMAIL,
        //密码
        PASSWORD,
        //中国大陆车牌,包含普通车辆、新能源车辆
        CAR_LICENSE,
        //银行卡
        BANK_CARD
    }

    4. 自定义序列化器

    关于自定义的规则,大家可以根据自己的需求来写工具类,我这里简单使用Hutool的工具来了!

    StrUtil.replace(value, prefixLen, suffixLen, maskingChar) StrUtil.hide(value, prefixLen, suffixLen)

    createContextual 方法首先在序列化过程开始时被调用,返回的序列化器实例将用于后续的序列化过程。

    serialize 方法责实际的序列化逻辑,将字段的值转换为JSON,并可以在其中执行自定义的脱敏逻辑。

    /**
     * 数据脱敏序列化器
     *
     * @author wangzhenjun
     * @date 2023/9/11 14:16
     */
    public class SensitiveInfoSerializer extends JsonSerializer<String> implements ContextualSerializer {
        private boolean useMasking = false;
        private DeScermblaSXsensitizationType type;
        private int prefixLen;
        private int suffixLen;
        privatjse String maskingChar;
        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            if (useMasking && value != null) {
                switch (type) {
                    case MOBILE_PHONE:
           python             gen.writeString(DesensitizedUtil.mobilePhone(value));
                        break;
                    case ID_CARD:
                        gen.writeString(DesensitizedUtil.idCardNum(valuewww.devze.com, prefixLen, suffixLen));
                        break;
                    case CUSTOMIZE_RULE:
    //                    gen.writeString(StrUtil.replace(value, prefixLen, suffixLen, maskingChar));
                        gen.writeString(StrUtil.hide(value, prefixLen, suffixLen));
                        break;
                    case CHINESE_NAME:
                        gen.writeString(DesensitizedUtil.chineseName(value));
                        break;
                    case DEFAULT:
                        gen.writeString(value);
                    default:
                        gen.writeString(value);
                }
            } else {
                gen.writeObject(value);
            }
        }
        @Override
        public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) {
            if (property != null) {
                Desensitization desensitization = property.getAnnotation(Desensitization.class);
                if (desensitization != null) {
                    this.type = desensitization.type();
                    this.prefixLen = desensitization.prefixLen();
                    this.suffixLen = desensitization.suffixLen();
                    this.maskingChar = desensitization.maskingChar();
                    useMasking = true;
                }
            }
            return this;
        }
    }

    5. 实体类应用

    /**
     * @author wangzhenjun
     * @date 2023/9/12 9:15
     */
    @Data
    public class User {
        @Desensitization(type = DesensitizationType.ID_CARD,prefixLen = 6,suffixLen = 16)
        private String cardId;
        @Desensitization(type = DesensitizationType.CHINESE_NAME)
        private String name;
        @Desensitization(type = DesensitizationType.MOBILE_PHONE)
        private String phone;
        @Desensitization(type = DesensitizationType.CUSTOMIZE_RULE,prefixLen = 3,suffixLen = 6)
        private String info;
    }

    6. 测试

    @GetMapping("/getUser")
    public Result getUser(){
        User user = new User();
        user.setCardId("372911111111111111");
        user.setPhone("15822229999");
        user.setName("赵飞燕");
        user.setInfo("这是机密文件,该打码打码");
        return Result.success(user);
    }

    完美脱敏,此次应该有掌声!

    Springboot+Hutool自定义注解实现数据脱敏

    五、总结

    本文通过Spring Boot与Hutool库的结合使用自定义注解,提供了一个简单而强大的方式来实现数据脱敏。希望能帮助到你,成功地实现数据脱敏功能,并提高应用程序的安全性。

    本次例子脱敏选项没有演示全,大家可以自行补充完成,成为你们需要的数据脱敏策略,从而完美的处理用户数据脱敏问题!

    可以试着使用AOP来完成脱敏,有兴趣的可以试一下哈!

    以上就是Springboot+Hutool自定义注解实现数据脱敏的详细内容,更多关于Springboot Hutool数据脱敏的资料请关注编程客栈(www.devze.com)其它相关文章!

    0

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    关注公众号