Jackson 2.x 系列【30】Spring Boot 集成之数据脱敏

有道无术,术尚可求,有术无道,止于术。

本系列Jackson 版本 2.17.0

本系列Spring Boot 版本 3.2.4

源码地址:https://gitee.com/pearl-organization/study-jaskson-demo

文章目录

    • 1. 概述
    • 2. 实现思路
    • 3. 案例演示
      • 3.1 脱敏规则
      • 3.2 自定义注解
      • 3.3 自定义序列化器
      • 3.4 测试

1. 概述

数据脱敏指对某些敏感信息通过脱敏规则进行数据的变形,实现敏感隐私数据的可靠保护。在开发、测试和其它非生产环境以及外包环境中安全地使用脱敏后的真实数据集。例如身份证号、手机号、卡号、客户号等个人信息都需要进行数据脱敏。

按照脱敏方式分为:

  • 静态数据脱敏:按照脱敏规则一次性完成大批量数据的变形转换处理
  • 动态数据脱敏:按照脱敏规则对于外部申请访问的数据进行即时处理并返回脱敏后的结果

随着 《网络安全法》 的颁布施行,对个人隐私数据的保护已经上升到法律层面。传统的应用系统普遍缺少对个人隐私数据的保护措施。数据脱敏,可实现在不需要对生产数据库中的数据进行任何改变的情况下,依据用户定义的脱敏规则,对生产数据库返回的数据进行专门的加密、遮盖和替换,确保生产环境的敏感数据能够得到保护。

2. 实现思路

一般可以在以下两种时机进行脱敏操作:

  • 数据库查询返回对象时
  • 序列化返回浏览器时
    在这里插入图片描述

Spring Web默认使用Jackson作为HTTP消息转换器的Json处理框架,那么可以自定义Jackson的序列化器对字段进行脱敏处理。

3. 案例演示

演示需求:

  • 身份证号显示为:43************6363
  • 手机号显示为:135****8888

3.1 脱敏规则

常用的脱敏规则有:

  • MD5:直接使用MD5计算
  • 遮盖脱敏:使用特殊字符遮盖,比如*
  • 替换脱敏:使用码表进行替换

演示需求中需要使用遮盖脱敏规则,将部分信息使用*进行遮盖。

3.2 自定义注解

参考Apache ShardingSphere的遮盖自 XY脱敏算法,定义一个脱敏注解,指定开始、结束位置,之间的字符都会使用指定的字符进行遮盖。

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.ANNOTATION_TYPE})
@JacksonAnnotationsInside
@JsonSerialize(using = MaskFromXToYJsonSerializer.class)
public @interface MaskFromXToYMask {/*** 起始位置 (从 0 开始计数)*/int from();/*** 结束位置(从 0 开始计数)*/int to();/*** 替换字符,默认**/String replaceChar() default "*";
}

定义身份证脱敏注解,遮盖2-13位置的字符:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@MaskFromXToYMask(from =2 ,to =13)
public @interface MaskIdNum {
}

定义手机号脱敏注解,遮盖3-6位置的字符:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@MaskFromXToYMask(from =3 ,to =6)
public @interface MaskPhone {
}

3.3 自定义序列化器

自定义序列化器MaskFromXToYJsonSerializer,获取字段上的脱敏注解,序列化时进行遮盖写出:

public class MaskFromXToYJsonSerializer extends StdSerializer<String> implements ContextualSerializer {private int from;private int to;private String replaceChar;public MaskFromXToYJsonSerializer(Class<String> t, int from, int to, String replaceChar) {super(t);this.from = from;this.to = to;this.replaceChar = replaceChar;}public MaskFromXToYJsonSerializer() {super(String.class);}/*** 序列化*/@Overridepublic void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {// 1. 校验if (this.from >= this.to) {throw new RuntimeException("起始位置不能大于等于结束位置");}if (StrUtil.isEmpty(this.replaceChar)) {throw new RuntimeException("替换字符不能为空");}// 2. 序列化if (StrUtil.isEmpty(str)) {// 为空jsonGenerator.writeString("");} else if (str.length() <= this.from) {// 字符长度小于开始位置jsonGenerator.writeString(str);} else {// 脱敏写出char[] chars = str.toCharArray();int i = this.from;for (int minLength = Math.min(this.to, chars.length - 1); i <= minLength; ++i) {chars[i] = this.replaceChar.charAt(0);}jsonGenerator.writeString(new String(chars));}}/*** 根据字段注解,返回序列化器,仅在在第一次序列化时调用*/@Overridepublic JsonSerializer<?> createContextual(SerializerProvider serializers, BeanProperty property) throws JsonMappingException {// 1. 属性为 Nullif (property == null) {return serializers.findNullValueSerializer(null);}// 2. 属性的类型Class<?> rawClass = property.getType().getRawClass();if (CharSequence.class.isAssignableFrom(rawClass)) {// 3. 字符串类型,返回脱敏序列化器MaskFromXToYMask annotation = property.getAnnotation(MaskFromXToYMask.class);if (annotation == null) {annotation = property.getContextAnnotation(MaskFromXToYMask.class);}if (annotation != null) {return new MaskFromXToYJsonSerializer(String.class, annotation.from(), annotation.to(), annotation.replaceChar());}}return serializers.findValueSerializer(property.getType(), property);}
}

3.4 测试

定义一个用户对象,添加脱敏注解:

@Data
@ToString
public class UserVO implements Serializable {Long id;String username;List<String> roleList;@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")Date birthday;@MaskIdNumString idNum;@MaskPhoneString phone;
}

常见一个访问接口:

    @RequestMapping("/test")public UserVO test() {UserVO userVO = new UserVO();userVO.setId(1699657986705854464L);userVO.setUsername("jack");userVO.setBirthday(new Date());userVO.setIdNum("430852195602056363");userVO.setPhone("13536238888");List<String> roleList = new ArrayList<>();roleList.add("管理员");roleList.add("经理");userVO.setRoleList(roleList);return userVO;}

访问接口:

在这里插入图片描述

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

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

相关文章

解决VSCode中“#include错误,请更新includePath“问题

目录 1、问题原因 2、解决办法 1、问题原因 在编写C程序时&#xff0c;想引用头文件但是出现如下提示&#xff1a; &#xff08;1&#xff09;首先检查要引用的头文件是否存在&#xff0c;位于哪里。 &#xff08;2&#xff09;如果头文件存在&#xff0c;在编译时提醒VSCo…

如何理解自然语言处理中的位置编码(Positional Encoding)

在自然语言处理和特别是在使用Transformer模型中,位置编码(Positional Encoding)是一个关键的概念。它们的作用是为模型提供序列中各个元素的位置信息。由于Transformer架构本身并不像循环神经网络(RNN)那样具有处理序列的固有能力,位置编码因此显得尤为重要。 为什么需…

【学习】服务器解决:重新分配同样端口号后,连不上VScode

原来服务器分配的环境有问题&#xff0c;重新分配了一下。还是同样的端口号&#xff0c;Xshell和xftp能够连接上&#xff0c;但是VScode连接不上。 问题解决: 清除本地 SSH 缓存中与远程主机相关的条目可以通过编辑 known_hosts 文件来实现。这个文件包含了您曾经连接过的远程主…

Linux报错处理:‘abrt-cli status’ timed out

最近登录服务器时出现报错&#xff0c;后来查阅资料发现是因为ssh登录时间很久&#xff0c;登录后出现abrt-cli status timed out 的报错。 1.问题分析 abrt-cli是ABRT(Automated Bug Reporting Tool)的命令行接口&#xff0c;用于在Linux系统中处理和报告程序崩溃。 如果abr…

[Qt的学习日常]--初识Qt

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、Qt的基本…

代码随想录算法训练营第四十六天| LeetCode139.单词拆分

一、LeetCode139.单词拆分 题目链接/文章讲解/视频讲解&#xff1a;https://programmercarl.com/0139.%E5%8D%95%E8%AF%8D%E6%8B%86%E5%88%86.html 状态&#xff1a;已解决 1.思路 单词明显就是物品&#xff0c;字符串s明显就是背包&#xff0c;那么问题就变成了物品能不能把背…

数据可视化———Tableau

基本认识&#xff1a; 维度&#xff1a;定性—字符串文本&#xff0c;日期和日期时间等等 度量&#xff1a;定量—连续值&#xff0c;一般属于数值 数据类型&#xff1a; 数值 日期/日期时间 字符串 布尔值 地理值 运算符 算数运算符&#xff1a;加减乘除,%取余&#xff0c;…

Stable Diffusion WebUI 使用 LoRA 调整风格——详细教程

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里&#xff0c;订阅后可阅读专栏内所有文章。 大家好&#xff0c;我是水滴~~ 本教程旨在深入探讨 LoRA 模型的奥秘&#xff0c;涵盖其基本概念、独特作用以及实操指南。我们将从下载和使用LoRA的步…

8.4.3 使用3:配置单臂路由实现VLAN间路由

1、实验目的 通过本实验可以掌握&#xff1a; 路由器以太网接口上的子接口配置和调试方法。单臂路由实现 VLAN间路由的配置和调试方法。 2、实验拓扑 实验拓扑如下图所示。 3、实验步骤 &#xff08;1&#xff09;配置交换机S1 S1(config)#vlan 2 S1(config-vlan)#exit S…

微服务项目实战-黑马头条(八):App端-文章ES搜索、MongoDB搜索记录和关键词联想

文章目录 一、今日内容介绍1.1 App端搜索-效果图1.2 今日内容 二、搭建ElasticSearch环境2.1 拉取镜像2.2 创建容器2.3 配置中文分词器 ik2.4 使用postman测试 三、app端文章搜索3.1 需求分析3.2 思路分析3.3 创建索引和映射3.4 数据初始化到索引库3.4.1 导入es-init到heima-le…

【七】jmeter5.5+influxdb2.0+prometheus+grafana

参考文章&#xff1a;https://blog.csdn.net/wenxingchen/article/details/126892890 https://blog.csdn.net/Zuo19960127/article/details/119726652 https://blog.csdn.net/shnu_cdk/article/details/132182858 promethus参考 由于自己下载的是infuldb2.0&#xff0c;所以按照…

grafana报错This panel requires Angular (deprecated)

1.原因 报错解释&#xff1a; Grafana在更新到7.0版本后&#xff0c;弃用了AngularJS&#xff08;一种用于构建大型Web应用的JavaScript框架&#xff09;。在早期的Grafana版本中&#xff0c;某些面板可能依赖于AngularJS&#xff0c;但这种依赖已经逐步被新的React或Vue面板所…

智慧安防视频监控EasyCVR视频汇聚平台无法自动播放视频的原因排查与解决

国标GB28181协议EasyCVR安防视频监控平台可以提供实时远程视频监控、视频录像、录像回放与存储、告警、语音对讲、云台控制、平台级联、磁盘阵列存储、视频集中存储、云存储等丰富的视频能力&#xff0c;平台支持7*24小时实时高清视频监控&#xff0c;能同时播放多路监控视频流…

Esp8266 - USB开关分享(开源)

文章目录 简介推广自己gitee项目地址:嘉立创项目地址&#xff1a;联系我们 功能演示视频原理图嘉立创PCB开源地址原理图PCB预览 固件烧录代码编译烧录1. 软件和驱动安装2. 代码编译1. 安装所需要的依赖库文件2. 下载源代码3. 烧录代码 使用说明1. 设备配网2. 打开设备操作页面3…

STM32 I²C通信

一、IC总线通信 1.1 IC总线特点 IC&#xff08;Inter Integrated Circuit&#xff0c;集成电路总线&#xff09;&#xff0c;通过串行数据线SDA&#xff08;Serial Data&#xff09;和串行时钟线SCL&#xff08;Serial Clock&#xff09;来完成数据的传输。 特点&#xff1a;…

深度学习-数据预处理

目录 创建一个人工数据集处理缺失的数据插入对inputs中的类别值或离散值&#xff0c;将NaN视为一个类别对inputs和outputs中的数值类型转换为张量格式 创建一个人工数据集 import os import pandas as pd os.makedirs(os.path.join(.., data), exist_okTrue) data_file os.p…

ESP-IDF下载与安装完整流程

本文主要看参考官网说明&#xff0c;如下&#xff1a; Windows 平台工具链的标准设置 - ESP32 - — ESP-IDF 编程指南 latest 文档 (espressif.com) 一、概述 ESP-IDF需要安装一些必备工具&#xff0c;才能围绕ESP32构建固件&#xff0c;包括&#xff1a; PythonGit交叉编译…

Docker搭建Maven仓库Nexus

文章目录 一、简介二、Docker部署三、仓库配置四、用户使用Maven五、管理Docker镜像 一、简介 Nexus Repository Manager&#xff08;简称Nexus&#xff09;是一个强大的仓库管理器。 Nexus3支持maven、docker、npm、yum、apt等多种仓库的管理。 建立了 Maven 私服后&#xf…

【JAVA】UDP与TCP套接字编程

目录 一、UDP数据报套接字编程 1、DatagramSocket API 2、DatagramPacket API 3、InetSocketAddress API 4、示例一 5、示例二 二、TCP流套接字编程 1、ServerSocket API 2、Socket API 3、TCP中的长短连接 4、示例一 5、示例二 一、UDP数据报套接字编程 1、Datag…

图像处理之模板匹配(C++)

图像处理之模板匹配&#xff08;C&#xff09; 文章目录 图像处理之模板匹配&#xff08;C&#xff09;前言一、基于灰度的模板匹配1.原理2.代码实现3.结果展示 总结 前言 模板匹配的算法包括基于灰度的匹配、基于特征的匹配、基于组件的匹配、基于相关性的匹配以及局部变形匹…