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

news/2024/9/18 6:00:59/ 标签: java, 开发语言

一、简介

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

基于Hutool 脱敏案列: 

java">@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)// 指定序列化器

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

2.2  脱了策略枚举类

java">@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 类进行脱敏

java">/*** 脱敏,使用默认的脱敏策略* <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 数据脱敏的序列化工具

  • 重写序列化接口,调用具体序列化策略
  • 重写创建上写文方法,指定当前处理的策略
java">@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*/@Overridepublic 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<?>*/@Overridepublic JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) throws JsonMappingException {// 获取注解Sensitive annotation = property.getAnnotation(Sensitive.class);//注解不为空 并且 类型为Stringif (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) {// 设置当前注解的策略为注解里面策略this.strategy = annotation.strategy();return this;}// 返回默认序列化器return prov.findValueSerializer(property.getType(), property);}
}
 注意:默认管理员不过滤需自行根据业务重写实现
java">public interface SensitiveService {/*** 是否脱敏*/boolean isSensitive();}

 三、测试案例

java">@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);}@Datastatic 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.ppmy.cn/news/1526029.html

相关文章

【超详细】Plaxis软件简介、 Plaxis Python API环境搭建、自动化建模、Python全自动实现、典型岩土工程案例实践应用

查看原文>>>【案例教程】PLAXIS软件丨自动化建模、典型岩土工程案例解析、模型应用、数据分析、图表制作 目录 第一部分&#xff1a;Plaxis软件简介及 Plaxis Python API环境搭建 第二部分&#xff1a;Plaxis自动化建模-基础案例 第三部分&#xff1a;进阶案例-Pyt…

neo4j docker 运行4.35 community 版本失败

运行脚本 sudo docker run -d \ --name container_name \ -p 27474:7474 \ -p 27687:7687 \ -v /home/neo4j/data:/data \ -v /home/neo4j/logs:/logs \ -v /home/neo4j/conf:/var/lib/neo4j/conf \ -v /home/neo4j/import:/var/lib/neo4j/import \ -v /home/lighthouse/tcmkg…

redis常见的数据类型?

参考&#xff1a;一文读懂Redis五种数据类型及应用场景 - 知乎 (zhihu.com) String 类型 String 类型&#xff1a;Redis 最基本的数据类型&#xff0c;它是二进制安全的&#xff0c;意味着你可以用它来存储任何类型的数据&#xff0c;如图片、序列化对象等。使用场景&#xff…

智慧交通基于yolov8的行人车辆检测计数系统python源码+onnx模型+精美GUI界面

【算法介绍】 智慧交通中&#xff0c;基于YOLOv8的行人车辆检测计数系统是一项高效、准确的技术解决方案。该系统利用YOLOv8这一先进的目标检测算法&#xff0c;结合深度学习技术&#xff0c;能够实时检测并准确计数道路上的行人和车辆。YOLOv8在保证检测速度的同时&#xff0…

SprinBoot+Vue爱老助老服务平台的设计与实现

目录 1 项目介绍2 项目截图3 核心代码3.1 Controller3.2 Service3.3 Dao3.4 application.yml3.5 SpringbootApplication3.5 Vue 4 数据库表设计5 文档参考6 计算机毕设选题推荐7 源码获取 1 项目介绍 博主个人介绍&#xff1a;CSDN认证博客专家&#xff0c;CSDN平台Java领域优质…

oracle 表的外键

表的外键 3.5.1表之间的三种关系 在数据库设计中&#xff0c;工作中经常会分析商业逻辑中的表的设计。在设计表的关系之前&#xff0c;需要先了解关系型数据库特点。关系数据库有如下特点&#xff1a; 关系型数据库采用了关系模型来组织数据的数据库。 关系型数据库的最大特点…

C#笔记11 获取线程及其信息,什么是优先级、单元状态、线程状态、执行状态、线程名称以及其他属性?

前文讲完了在C#中线程怎么创建&#xff0c;怎么删除&#xff0c;怎么启动&#xff0c;怎么阻止。 现在来看看线程本身的属性。 当前线程 首先要获得当前线程&#xff0c;才能获取线程信息&#xff0c;此属性用于获取当前运行的线程。此属性可用于获取代码当前执行所在的线程…

qt下两种方式读取opencv 图片各个通道的值

qt下两种方式读取opencv 图片各个通道的值 Mat srcImg imread("D:\\1.jpg");if(srcImg.empty()){QMessageBox::information(this,"警告","图片读取失败&#xff0c;请检查图片路径&#xff01;");return;}Mat imgShow ;cvtColor(srcImg, imgSho…

企微机器人:企业数字化转型的得力助手

在数字化转型的浪潮中&#xff0c;企业对于提高运营效率、降低人力成本的需求日益迫切。企微机器人&#xff0c;作为基于企业微信平台开发的一种智能工具&#xff0c;以其高度自动化、灵活性强、安全性高和易于使用的特点&#xff0c;迅速成为企业内部的得力助手。本文将深入探…

udp的广播,多播,单播 demo

enum class EMsgType:uint8_t { EMSGT_SINGLE,//单播 EMSGT_MULTICAST,//多播 EMSGT_BROADCAST,//广播 }; sendSocket new QUdpSocket(this); sendSocket->setSocketOption(QAbstractSocket::MulticastTtlOption, 1); sendSocket->bind(QHostAddress::AnyIPv4, 0,QUdpSoc…

Qt 弹出菜单右键菜单 QMenu 设置不同颜色的子项

概述 在Qt中&#xff0c;可以使用样式表&#xff08;StyleSheet&#xff09;来自定义 QMenu 的外观&#xff0c;包括其子项&#xff08;如菜单项QAction&#xff09;的颜色。但是&#xff0c;这通常可以设置 QMenu 的整体样式&#xff0c;而不能单独设置某个子项的颜色。不过&…

Redis:处理缓存穿透的两种方法

缓存穿透&#xff1a;客户端请求的数据在缓存和数据库中都不存在&#xff0c;这样缓存永远不能生效&#xff0c;请求都会直接发送到数据库 解决方案&#xff1a; 1.缓存空对象 查完数据库后&#xff0c;将该数据以空值缓存进redis中&#xff0c;同时增加命中时对命中空值的判…

【乐吾乐大屏可视化组态编辑器】使用手册

1 总览 开始设计&#xff1a;大屏可视化设计器 - 乐吾乐Le5le 1.1 画布 画布即绘画区域&#xff0c;将图形拖拽到画布进行编辑&#xff0c;绘制大屏。 1.2 菜单栏 顶部菜单导航&#xff0c;一级菜单可设置Logo、公司名称、文件编辑、常用编辑、查看、帮助&#xff0c;设置大…

尚品汇-订单拆单、支付宝关闭交易、关闭过期订单整合(五十)

目录&#xff1a; &#xff08;1&#xff09;拆单接口 &#xff08;2&#xff09;取消订单业务补充关闭支付记录 &#xff08;3&#xff09;支付宝关闭交易 &#xff08;4&#xff09;查询支付交易记录 &#xff08;5&#xff09;PaymentFeignClient 远程接口 &#xff08…

【Kubernetes】常见面试题汇总(十)

目录 29.简述 Kubernetes 自动扩容机制&#xff1f; 30.简述 Kubernetes Service 类型&#xff1f; 31.简述 Kubernetes Service 分发后端的策略&#xff1f; 32.简述 Kubernetes Headless Service &#xff1f; 29.简述 Kubernetes 自动扩容机制&#xff1f; &#xff08;…

828华为云征文 | 华为云X实例服务器上部署知识图谱项目的详细指南

前言 知识图谱作为数据整合、语义分析和人工智能的重要基础&#xff0c;逐渐被广泛应用于各类领域。其通过结构化数据和关系映射&#xff0c;帮助用户更好地理解数据背后的意义。要成功构建和部署知识图谱项目&#xff0c;强大的计算资源和高效的存储查询能力至关重要。华为云X…

【App】React Native

React Native 的优势&#xff1a; 开发体验好 用统一的代码规范开发移动端程序&#xff0c;不用关注移动端的差异.开发成本低 开发一次&#xff0c;可以生成 Android 和 IOS 俩个系统上的 App学习成本低 只要掌握 JavaScript 和 React 就可以进行移动端开发 React Native 的不…

可解释性机器学习中的局部解释

可解释性机器学习可以被分成两大类&#xff0c;第一大类叫做局部的解释&#xff0c;第二大类叫做全局的 解释&#xff0c;如图 1 所示。局部的解释是&#xff0c;比如有一个图像分类器&#xff0c;输入一张图片&#xff0c;它会判断出 是一只猫&#xff0c;机器要回答问题是为什…

SpringCloud Alibaba入门简介

1、诞生 2018.10.31&#xff0c;Spring Cloud Alibaba 正式入驻了 Spring Cloud 官方孵化器&#xff0c;并在 Maven 中央库发布了第一个版本。 2、是什么&#xff0c;去哪下 官网&#xff1a;Spring Cloud Alibaba官网_基于Springboot的微服务教程-阿里云-阿里云Spring Cloud …

Python(PyTorch)和MATLAB及Rust和C++结构相似度指数测量导图

&#x1f3af;要点 量化检查图像压缩质量低分辨率多光谱和高分辨率图像实现超分辨率分析图像质量图像索引/多尺度结构相似度指数和光谱角映射器及视觉信息保真度多种指标峰值信噪比和结构相似度指数测量结构相似性图像分类PNG和JPEG图像相似性近似算法图像压缩&#xff0c;视频…