数据脱敏 (Jackson + Hutool 工具包)

news2024/9/19 13:26:26

一、简介

系统使用 Jackson 序列化策略对标注了 Sensitive 注解的属性进行脱敏处理

基于Hutool 脱敏案列: 

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside// 表示只对有此注解的字段进行序列化
@JsonSerialize(using = SensitiveJsonSerializer.class)// 指定序列化器
public @interface Sensitive {
    SensitiveStrategy strategy();
}

我们以身份证号码为例:

// 5***************1X
DesensitizedUtil.idCardNum("51343620000320711X", 1, 2);

对于约定俗成的脱敏,我们可以不用指定隐藏位数,比如手机号:

// 180****1999
DesensitizedUtil.mobilePhone("18049531999");

当然还有一些简单粗暴的脱敏,比如密码,只保留了位数信息:

// **********
DesensitizedUtil.password("1234567890");

 二、若依框架脱敏流程

2.1 注解类

@JacksonAnnotationsInside// 表示只对有此注解的字段进行序列化
@JsonSerialize(using = SensitiveJsonSerializer.class)// 指定序列化器

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside// 表示只对有此注解的字段进行序列化
@JsonSerialize(using = SensitiveJsonSerializer.class)// 指定序列化器
public @interface Sensitive {
    SensitiveStrategy strategy();
}

2.2  脱了策略枚举类

@AllArgsConstructor
public enum SensitiveStrategy {

    /**
     * 身份证脱敏
     */
    ID_CARD(s -> DesensitizedUtil.idCardNum(s, 3, 4)),

    /**
     * 手机号脱敏
     */ PHONE(DesensitizedUtil::mobilePhone),


    /**
     * 地址脱敏
     */
    ADDRESS(s -> DesensitizedUtil.address(s, 8)),

    /**
     * 邮箱脱敏
     */
    EMAIL(DesensitizedUtil::email),

    /**
     * 银行卡
     */
    BANK_CARD(DesensitizedUtil::bankCard);

    //可自行添加其他脱敏策略

    private final Function<String, String> desensitizer;

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

 使用的是HuTool包中的 DesensitizedUtil 类进行脱敏

/**
	 * 脱敏,使用默认的脱敏策略
	 * <pre>
	 * DesensitizedUtil.desensitized("100", DesensitizedUtil.DesensitizedType.USER_ID)) =  "0"
	 * DesensitizedUtil.desensitized("段正淳", DesensitizedUtil.DesensitizedType.CHINESE_NAME)) = "段**"
	 * DesensitizedUtil.desensitized("51343620000320711X", DesensitizedUtil.DesensitizedType.ID_CARD)) = "5***************1X"
	 * DesensitizedUtil.desensitized("09157518479", DesensitizedUtil.DesensitizedType.FIXED_PHONE)) = "0915*****79"
	 * DesensitizedUtil.desensitized("18049531999", DesensitizedUtil.DesensitizedType.MOBILE_PHONE)) = "180****1999"
	 * DesensitizedUtil.desensitized("北京市海淀区马连洼街道289号", DesensitizedUtil.DesensitizedType.ADDRESS)) = "北京市海淀区马********"
	 * DesensitizedUtil.desensitized("duandazhi-jack@gmail.com.cn", DesensitizedUtil.DesensitizedType.EMAIL)) = "d*************@gmail.com.cn"
	 * DesensitizedUtil.desensitized("1234567890", DesensitizedUtil.DesensitizedType.PASSWORD)) = "**********"
	 * DesensitizedUtil.desensitized("苏D40000", DesensitizedUtil.DesensitizedType.CAR_LICENSE)) = "苏D4***0"
	 * DesensitizedUtil.desensitized("11011111222233333256", DesensitizedUtil.DesensitizedType.BANK_CARD)) = "1101 **** **** **** 3256"
	 * DesensitizedUtil.desensitized("192.168.1.1", DesensitizedUtil.DesensitizedType.IPV4)) = "192.*.*.*"
	 * </pre>
	 *
	 * @param str              字符串
	 * @param desensitizedType 脱敏类型;可以脱敏:用户id、中文名、身份证号、座机号、手机号、地址、电子邮件、密码
	 * @return 脱敏之后的字符串
	 * @author dazer and neusoft and qiaomu
	 * @since 5.6.2
	 */

 2.3 数据脱敏的序列化工具

  • 重写序列化接口,调用具体序列化策略
  • 重写创建上写文方法,指定当前处理的策略
@Slf4j
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer {

    private SensitiveStrategy strategy;

    /**
     * <简述> 重写序列化方法
     * <详细描述>
     * @author syf
     * @date 2024/9/14 17:01
     * @param value
     * @param gen
     * @param serializers
     */
    @Override
    public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        try {
            // 获取注解
            SensitiveService sensitiveService = SpringUtils.getBean(SensitiveService.class);
            // 判断是否开启脱敏
            if (ObjectUtil.isNotNull(sensitiveService) && sensitiveService.isSensitive()) {
                // 调用策略 strategy.desensitizer().apply(value), gen.writeString写入值
                gen.writeString(strategy.desensitizer().apply(value));
            } else {
                gen.writeString(value);
            }
        } catch (BeansException e) {
            log.error("脱敏实现不存在, 采用默认处理 => {}", e.getMessage());
            gen.writeString(value);
        }
    }

    /**
     * <简述>重写创建上下文方法
     * <详细描述>
     * @author syf
     * @date 2024/9/14 16:54
     * @param prov
     * @param property
     * @return com.fasterxml.jackson.databind.JsonSerializer<?>
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {
        // 获取注解
        Sensitive annotation = property.getAnnotation(Sensitive.class);
        //注解不为空 并且 类型为String
        if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {
            // 设置当前注解的策略为注解里面策略
            this.strategy = annotation.strategy();
            return this;
        }
        // 返回默认序列化器
        return prov.findValueSerializer(property.getType(), property);
    }
}
 注意:
 默认管理员不过滤
 需自行根据业务重写实现
public interface SensitiveService {

    /**
     * 是否脱敏
     */
    boolean isSensitive();

}

 三、测试案例

@RestController
@RequestMapping("/demo/sensitive")
public class TestSensitiveController extends BaseController {

    /**
     * 测试数据脱敏
     */
    @GetMapping("/test")
    public R<TestSensitive> test() {
        TestSensitive testSensitive = new TestSensitive();
        testSensitive.setIdCard("210397198608215431");
        testSensitive.setPhone("17640125371");
        testSensitive.setAddress("北京市朝阳区某某四合院1203室");
        testSensitive.setEmail("17640125371@163.com");
        testSensitive.setBankCard("6226456952351452853");
        return R.ok(testSensitive);
    }

    @Data
    static class TestSensitive {

        /**
         * 身份证
         */
        @Sensitive(strategy = SensitiveStrategy.ID_CARD)
        private String idCard;

        /**
         * 电话
         */
        @Sensitive(strategy = SensitiveStrategy.PHONE)
        private String phone;

        /**
         * 地址
         */
        @Sensitive(strategy = SensitiveStrategy.ADDRESS)
        private String address;

        /**
         * 邮箱
         */
        @Sensitive(strategy = SensitiveStrategy.EMAIL)
        private String email;

        /**
         * 银行卡
         */
        @Sensitive(strategy = SensitiveStrategy.BANK_CARD)
        private String bankCard;

    }

}

 

  博主精心整理专栏,CV大法即可用,感谢您小手点一点 手动跪拜:  

1- SpringBoot框架常用配置(若依),代码解读:

http://t.csdnimg.cn/jpsSN

2- java常用工具类整理,示例演示:

http://t.csdnimg.cn/gmCfJ

3- CompletableFuture 异步编排实际代码展示

http://t.csdnimg.cn/ZuC0N

4- XXL-JOB 详细学习,手把手带入门

http://t.csdnimg.cn/lyR7Y

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2146338.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL高阶1831-每天的最大交易

题目 编写一个解决方案&#xff0c;报告每天交易金额 amount 最大 的交易 ID 。如果一天中有多个这样的交易&#xff0c;返回这些交易的 ID 。 返回结果根据 transaction_id 升序排列。 准备数据 Create table If Not Exists Transactions (transaction_id int, day date, …

吹爆上海交大的大模型实战教程!!—《动手学大模型》附实战教程及ppt

今天分享一个上海交大的免费的大模型课程&#xff0c;有相关教程文档和Slides&#xff0c;目前是2.2K星标&#xff0c;还是挺火的&#xff01; 《动手学大模型》系列编程实践教程&#xff0c; 由上海交通大学2024年春季《人工智能安全技术》课程&#xff08;NIS3353&#xff09…

深入剖析Docker容器安全:挑战与应对策略

随着容器技术的广泛应用&#xff0c;Docker已成为现代应用开发和部署的核心工具。它通过轻量级虚拟化技术实现应用的隔离与封装&#xff0c;提高了资源利用率。然而&#xff0c;随着Docker的流行&#xff0c;其安全问题也成为关注焦点。容器化技术虽然提供了良好的资源隔离&…

SHAP 模型可视化 + 参数搜索策略在轴承故障诊断中的应用

往期精彩内容&#xff1a; Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承数据解读与分类处理 Python轴承故障诊断入门教学-CSDN博客 Python轴承故障诊断 (13)基于故障信号特征提取的超强机器学习识别模型-CSDN博客 Python轴承故障诊断 (14)高创新故障识别模型-CSDN…

Linux用户组管理

目录 一、增删改用户组 1.1. 创建一个新的用户组 1.2. 创建用户组并指定ID 1.3. 修改用户组的名 1.4. 修改用户组的ID 1.5. 删除一个用户组 二、用户组中的用户操作 2.1. 添加用户到一个已存在的用户组 2.2. 从用户组中移除用户 注&#xff1a;本章内容全部基于Centos…

论文阅读--Planning-oriented Autonomous Driving(二)

自动驾驶框架的各种设计比较。 ( a )大多数工业解决方案针对不同的任务部署不同的模型。 ( b )多任务学习方案共享一个具有分割任务头的主干。 ( c )端到端范式将感知和预测模块统一起来。以往的尝试要么采用( c.1 )中对规划的直接优化&#xff0c;要么采用( c.2 )中的部分元…

基于PHP的高校毕业生就业服务平台

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于phpMySQL的高校毕业生就业…

html,css基础知识点笔记(二)

9.18&#xff08;二&#xff09; 本文主要教列表的样式设计 1&#xff09;文本溢出 效果图 文字限制一行显示几个字&#xff0c;多余打点 line-height: 1.8em; white-space: nowrap; width: 40em; overflow: hidden; text-overflow: ellipsis;em表示一个文字的大小单位&…

MySQL实战面试题(附案例答案+建表语句+模拟数据+案例深度解析),练完直接碾压面试官

知识点思维导图 案例1 建表语句与模拟数据 用户表 users CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, email VARCHAR(100) NOT NULL UNIQUE, signup_date DATE NOT NULL ); INSERT INTO users (username, email, signu…

C++ | Leetcode C++题解之第416题分割等和子集

题目&#xff1a; 题解&#xff1a; class Solution { public:bool canPartition(vector<int>& nums) {int n nums.size();if (n < 2) {return false;}int sum 0, maxNum 0;for (auto& num : nums) {sum num;maxNum max(maxNum, num);}if (sum & 1)…

ICL、CoT、ReAct个人记录

In-Context Learning(ICL) 将一些带有标签的样本拼接起来&#xff0c;作为prompt的一部分。不涉及梯度更新&#xff0c;因此不属于ft CoT 但是其依然属于静态的黑盒子&#xff0c;依靠其推理的结果很难与真实知识保持一致&#xff0c;且限制了推理过程中及时反应和知识更新的…

技术生态系统中的绿色可持续发展与商业模式创新:The Open Group 2024大会引领未来发展趋势

绿色转型与商业模式创新在技术生态系统中的核心地位 在全球范围内&#xff0c;企业正面临着双重挑战&#xff1a;如何在推动技术生态系统创新的同时&#xff0c;践行可持续发展的承诺。随着气候变化压力的增加&#xff0c;绿色经济成为企业发展和创新的必然趋势。然而&#xf…

Python基础(八)——MySql数据库

一.数据库 【库——>表——>数据】 借助数据库对数据进行组织存储&#xff0c;借助SQL语言对数据库、数据进行操作管理 Mysql数据库 下载&#xff1a;https://www.mysql.com/ 查看是否安装配置成功&#xff1a; 安装DBeaver用于Mysql数据库图形化 安装&#xff1a;…

Python语言学习-pandas库学习

一、什么是Pandas库 Pandas是python的第三方库&#xff0c;他用于灵活的数据操作&#xff0c;数据可视化&#xff0c;数据清洗&#xff0c;数据的聚合和转换&#xff0c;数据的可视化 二、安装pandas库 在终端中运行 pip install pandas 导入Pandas库并重命名为pd import …

腹腔镜工具识别与定位系统源码分享

腹腔镜工具识别与定位检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Comp…

电机知识总结

一.直流无刷电机&#xff08;BLDC&#xff09; 27N30P指有27个槽&#xff0c;30的极数&#xff0c;它的极对数&#xff1a;30/215,所以是15对极。 N必须是3的倍数&#xff0c;P必须是偶数&#xff0c; 电角度是电气特性&#xff0c;机械角度是空间特性&#xff0c;必须指明是谁…

进击J7:对于ResNeXt-50算法的思考

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 本周任务是自行探索解决问题&#xff0c;通过此次思考过程逐渐将知识层面的学习过渡到能力层面的培养上。 一、任务 &#x1f4cc; **你需要解决的疑问&…

MFC 使用细节

MFC 使用细节 1. MFC&#xff1a;在共享 DLL 中使用 MFC 或者在静态库中使用 MFC 的区别 在共享 DLL 中使用 MFC&#xff1a;这种方式下&#xff0c;MFC DLL 的内容不会包含在您的 EXE 文件中。因此&#xff0c;生成的 EXE 文件较小&#xff0c;但运行时需要系统中有相关的 M…

「iOS」——单例模式

iOS学习 前言单例模式的概念单例模式的优缺点单例模式的两种模式懒汉模式饿汉模式单例模式的写法 总结 前言 在一开始学习OC的时候&#xff0c;我们初步接触过单例模式。在学习定时器与视图移动的控件中&#xff0c;我们初步意识到单例模式的重要性。对于我们需要保持的控件&a…

热点创新 | 基于 KANConv-GRU并行的多步预测模型

多步预测全家桶重大更新&#xff01;&#xff01;&#xff01; 本期我们继续更新多步预测全家桶&#xff0c;把 KAN 和 CKAN ( Convolutional Kolmogorov-Arnold Network ) 应用到多步预测模型里面&#xff0c;我们新增了关于KAN、KANConv、CNN-KAN、LSTM-KAN、TCN-KAN、Trans…