SpringBoot 一个注解实现数据脱敏

什么是数据脱敏

数据脱敏是指对某些敏感信息,例如姓名、身份证号码、手机号、固定电话、银行卡号、邮箱等个人信息,通过脱敏算法进行数据变形,以保护敏感隐私数据。

数据脱敏通常涉及以下几种主要方法:

  1. 替换: 将原始数据中的敏感信息替换为不敏感的等效数据。例如,将真实姓名替换为随机生成的名称,将电话号码替换为虚构的号码。
  2. 扰动: 对数据进行微小的变化,以使其仍然保持某种程度的统计一致性,但不足以使个人身份可被轻松识别。这包括添加噪声或对数值进行微小的随机化。
  3. 屏蔽: 将敏感信息从数据中删除或隐藏。例如,用特定字符或占位符替换敏感文本。
  4. 一般化: 减少数据的精确度,使得数据更加模糊。例如,将年龄精确到天数的数据一般化为年龄范围。
  5. 删除: 完全删除不必要的敏感信息。

Spring Boot自定义注解实现数据脱敏

依赖版本

  • JDK 17
  • Spring Boot 3.2.0
  • Hutool-core 5.8.24 (非必须)

源码地址:Gitee

导入依赖

<dependencies><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>5.8.24</version></dependency>
</dependencies>

自定义脱敏类型枚举

/*** @description 数据脱敏策略枚举*/
public enum DesensitizationTypeEnum {//自定义CUSTOM,//用户idUSER_ID,//中文名CHINESE_NAME,//身份证号ID_CARD,//座机号FIXED_PHONE,//手机号MOBILE_PHONE,//地址ADDRESS,//电子邮件EMAIL,//密码PASSWORD,//中国大陆车牌,包含普通车辆、新能源车辆CAR_LICENSE,//银行卡BANK_CARD
}

自定义脱敏序列化器

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.DesensitizedUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.yiyan.study.annotation.Desensitization;
import com.yiyan.study.enums.DesensitizationTypeEnum;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;import java.io.IOException;
import java.util.Objects;/*** @description 自定义脱敏序列化类*/
@AllArgsConstructor
@NoArgsConstructor
public class DesensitizationSerialize extends JsonSerializer<String> implements ContextualSerializer {private DesensitizationTypeEnum type;private Integer startInclude;private Integer endExclude;@Overridepublic void serialize(String str, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {switch (type) {// 自定义类型脱敏case CUSTOM -> jsonGenerator.writeString(CharSequenceUtil.hide(String.valueOf(str), startInclude,endExclude >= startInclude ? endExclude : str.length() + endExclude));// userId脱敏case USER_ID -> jsonGenerator.writeString(String.valueOf(DesensitizedUtil.userId()));// 中文姓名脱敏case CHINESE_NAME -> jsonGenerator.writeString(CharSequenceUtil.hide(String.valueOf(str), 1, str.length()));// 身份证脱敏case ID_CARD -> jsonGenerator.writeString(DesensitizedUtil.idCardNum(String.valueOf(str), 1, 2));// 固定电话脱敏case FIXED_PHONE -> jsonGenerator.writeString(DesensitizedUtil.fixedPhone(String.valueOf(str)));// 手机号脱敏case MOBILE_PHONE -> jsonGenerator.writeString(DesensitizedUtil.mobilePhone(String.valueOf(str)));// 地址脱敏case ADDRESS -> jsonGenerator.writeString(DesensitizedUtil.address(String.valueOf(str), 8));// 邮箱脱敏case EMAIL -> jsonGenerator.writeString(DesensitizedUtil.email(String.valueOf(str)));// 密码脱敏case PASSWORD -> jsonGenerator.writeString(DesensitizedUtil.password(String.valueOf(str)));// 中国车牌脱敏case CAR_LICENSE -> jsonGenerator.writeString(DesensitizedUtil.carLicense(String.valueOf(str)));// 银行卡脱敏case BANK_CARD -> jsonGenerator.writeString(DesensitizedUtil.bankCard(String.valueOf(str)));}}@Overridepublic JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {if (beanProperty != null) {// 判断数据类型是否为String类型if (Objects.equals(beanProperty.getType().getRawClass(), String.class)) {// 获取定义的注解Desensitization desensitization = beanProperty.getAnnotation(Desensitization.class);if (desensitization == null) {desensitization = beanProperty.getContextAnnotation(Desensitization.class);}if (desensitization != null) {return new DesensitizationSerialize(desensitization.type(), desensitization.startInclude(),desensitization.endExclude());}}return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);}return serializerProvider.findNullValueSerializer(null);}
}

自定义脱敏注解

import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.yiyan.study.enums.DesensitizationTypeEnum;
import com.yiyan.study.serialize.DesensitizationSerialize;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 脱敏注解*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@JacksonAnnotationsInside
@JsonSerialize(using = DesensitizationSerialize.class)
public @interface Desensitization {/*** 脱敏数据类型,CUSTOM注解下,startInclude和endExclude生效*/DesensitizationTypeEnum type() default DesensitizationTypeEnum.CUSTOM;/*** 脱敏开始位置(包含)*/int startInclude() default 0;/*** 脱敏结束位置(不包含)*/int endExclude() default 0;
}

数据脱敏测试

定义测试对象

import com.yiyan.study.annotation.Desensitization;
import com.yiyan.study.enums.DesensitizationTypeEnum;
import lombok.Builder;
import lombok.Data;import java.io.Serializable;@Data
@Builder
public class DesensitizationDTO implements Serializable {@Desensitization(type = DesensitizationTypeEnum.CHINESE_NAME)private String username;@Desensitization(type = DesensitizationTypeEnum.EMAIL)private String email;@Desensitization(type = DesensitizationTypeEnum.ADDRESS)private String address;@Desensitization(type = DesensitizationTypeEnum.MOBILE_PHONE)private String phoneNumber;@Desensitization(type = DesensitizationTypeEnum.CUSTOM, startInclude = 1, endExclude = -2)private String note;
}

测试接口

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yiyan.study.model.DesensitizationDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;/*** 启动类*/
@SpringBootApplication
@Slf4j
@RestController
public class DesensitizationApplication {private static final DesensitizationDTO dto = com.yiyan.study.model.DesensitizationDTO.builder().username("小李").phoneNumber("12300000456").email("li@gmail.com").address("XX.YY.DD.FF").note("123456789").build();public static void main(String[] args) throws JsonProcessingException {SpringApplication.run(DesensitizationApplication.class, args);ObjectMapper mapper = new ObjectMapper();String s = mapper.writeValueAsString(dto);log.info("Json : {}", s);}@GetMapping("/test")public DesensitizationDTO desensitizationTest() {return dto;}
}

springboot3-数据脱敏

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

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

相关文章

如何使用Docker部署Swagger Editor结合内网穿透实现远程编辑API文档

文章目录 Swagger Editor本地接口文档公网远程访问1. 部署Swagger Editor2. Linux安装Cpolar3. 配置Swagger Editor公网地址4. 远程访问Swagger Editor5. 固定Swagger Editor公网地址 Swagger Editor本地接口文档公网远程访问 Swagger Editor是一个用于编写OpenAPI规范的开源编…

[python]matplotlib

整体图示 .ipynb 转换md时候图片不能通知携带&#xff0c;所有图片失效&#xff0c;不过直接运行代码可以执行 figure figure,axes与axis import matplotlib.pyplot as plt figplt.figure() fig2plt.subplots() fig3,axsplt.subplots(2,2) plt.show()<Figure size 640x480 …

windows2012 安装mysql5.7

windows2012 安装mysql5.7 1.安装1.解压文件夹2.把my文件拷入没有sql安装目录3.编辑my文件4.按照下方进行配置5.cmd进入bin目录6.出现丢失文件7.安装这个文件即可解决8.开始进行安装&#xff0c;输入mysqld install9.初始化mysql&#xff08;mysqld --initialize --console&…

Mybatis行为配置之Ⅳ—日志

专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 Mybatis枚举类型处理和类型处理器 再谈动态SQL Mybatis配置入门 Mybatis行为配置之Ⅰ—缓存 Mybatis行为配置…

Hive学习(13)lag和lead函数取偏移量

hive里面lag函数 在数据处理和分析中&#xff0c;窗口函数是一种重要的技术&#xff0c;用于在数据集中执行聚合和分析操作。Hive作为一种大数据处理框架&#xff0c;也提供了窗口函数的支持。在Hive中&#xff0c;Lag函数是一种常用的窗口函数&#xff0c;可以用于计算前一行…

项目记录:利用Redis实现缓存以提升查询效率

一、概述 当我们查询所有数据时&#xff0c;如果缓存中没有&#xff0c;则去数据库查询&#xff0c;如果有&#xff0c;直接查缓存的数据就行。注意定期更新缓存数据。 二、主体代码 private static final String ROOM_SCHEDULES_HASH "RoomSchedules";Overridepu…

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的图像剪切(ROI)功能(C++)

Baumer工业相机堡盟工业相机如何通过NEOAPI SDK设置相机的图像剪切&#xff08;ROI&#xff09;功能&#xff08;C&#xff09; Baumer工业相机Baumer工业相机的图像剪切&#xff08;ROI&#xff09;功能的技术背景CameraExplorer如何使用图像剪切&#xff08;ROI&#xff09;功…

计算机网络——传输层(五)

前言&#xff1a; 最重要的网络层我们已经学习完了&#xff0c;下面让我们再往上一层&#xff0c;对网络层的上一层传输层进行一个学习与了解&#xff0c;学习网络层的基本概念和网络层中的TCP协议和UDP协议 目录 ​编辑一、传输层的概述&#xff1a; 1.传输层&#xff1a; …

【Elasticsearch源码】 分片恢复分析

带着疑问学源码&#xff0c;第七篇&#xff1a;Elasticsearch 分片恢复分析 代码分析基于&#xff1a;https://github.com/jiankunking/elasticsearch Elasticsearch 8.0.0-SNAPSHOT 目的 在看源码之前先梳理一下&#xff0c;自己对于分片恢复的疑问点&#xff1a; 网上对于E…

Docker之网络配置

目录 1.网络概念 网络相关的有ip,子网掩码,网关,DNS,端口号 1.1 ip是什么? ip是唯一定位一台网上计算机 Ip地址的分类: IPV4: 4字节32位整数&#xff0c;并分成4段8位的二进制数&#xff0c;每8位之间用圆点隔开&#xff0c;每8位整数可以转换为一个0~255的十进制整数 【例…

ios苹果app应用程序录屏开发有哪些难点和注意点?

首先&#xff0c;让我们简单了解一下iOS录屏的基本原理。iOS录屏是指将设备屏幕上的内容实时捕捉并保存为视频文件的过程。这在教学、演示和用户支持等场景中非常有用。iOS录屏可以通过使用ReplayKit框架来实现&#xff0c;该框架提供了一套API&#xff0c;用于捕捉屏幕上的内容…

【数据结构-单链表】(C语言版本)

今天分享的是数据结构有关单链表的操作和实践&#xff08;图解法&#xff0c;图变化更利于理解&#xff09; 记录宗旨&#x1f4dd;&#xff1a; 眼&#xff08;脑&#xff09;过千遍&#xff0c;不如手过一遍。 我们都知道单链表是一种常见的链表数据结构&#xff0c;由一系列…

SpringMVC-HelloWorld

一、SpringMVC简介 1.1 SpringMVC和三层架构 MVC是一种软件架构思想&#xff0c;将软件按照模型、视图和控制器三个部分划分。 M&#xff1a;model&#xff0c;模型层&#xff0c;指工程中的JavaBean&#xff0c;用于处理数据。JavaBean分为两类&#xff1a; 实体类Bean&…

KG+LLM(一)KnowGPT: Black-Box Knowledge Injection for Large Language Models

论文链接&#xff1a;2023.12-https://arxiv.org/pdf/2312.06185.pdf 1.Background & Motivation 目前生成式的语言模型&#xff0c;如ChatGPT等在通用领域获得了巨大的成功&#xff0c;但在专业领域&#xff0c;由于缺乏相关事实性知识&#xff0c;LLM往往会产生不准确的…

瑞吉外卖项目详细总结

文章目录 瑞吉外卖1.技术栈2.项目文件架构3.业务功能模块&#xff08;例子&#xff09;3.1管理员登录接口层(Controller)3.2管理员登录实现层(ServiceImpl)3.3管理员登录服务层&#xff08;Service&#xff09;3.4管理员登录Mapper层 4.公共模块4.1 BaseContext&#xff08;保存…

王力机器人安全门|用细节开拓高端精致家居生活

细微之处见风范,毫厘之优定乾坤。在追求高端品质的道路上,细节往往是最有力的诠释。如在入户门的选择方面,考虑到老人、孩子、宠物等每一位家庭成员不同需求的设计、科技运用才称得上是充满人性化、品质化的高端细节,幸福感直抵心灵。在该方面,王力机器人安全门做出了表率,每一…

【连接池】-从源码到适配(下),使用dynamic-datasource导致连接池没生效(升级版本)

写在前面 书接上文&#xff0c;连接池没生效&#xff0c;启用了一个什么默认的连接池。具体是什么&#xff0c;一起来看看源码吧。 目录 写在前面一、问题描述二、本地调试三、升级dynamic-datasource四、新的问题&#xff08;一&#xff09;数据源初始化问题&#xff08;二&am…

公司创建百度百科需要哪些内容?

一个公司或是一个品牌想要让自己更有身份&#xff0c;更有知名度&#xff0c;更有含金量&#xff0c;百度百科词条是必不可少的。通过百度百科展示公司的详细信息&#xff0c;有助于增强用户对公司的信任感&#xff0c;提高企业形象。通过百度百科展示公司的发展历程、领导团队…

ASP.Net实现汽车添加查询(三层架构,含照片)

演示功能&#xff1a; 点击启动生成页面 点击搜索模糊查询 点击添加跳转新界面 此处设置文本框多行 点击Button添加 步骤&#xff1a; 1、建文件 下图是三层架构列表&#xff0c;Models里面有模拟数据库中列的类&#xff0c;DAL中有DBHelper和service,BLL中有BllManager文件…

TiDB 7.5 LTS 发版丨提升规模化场景下关键应用的稳定性和成本的灵活性

互联网时代&#xff0c;数据的迅猛增长给数据库带来了可扩展性的挑战&#xff0c;Gen AI 带来的数据暴增更加剧了这种挑战。传统的数据分片已经不能承载新时代数据暴增的需求&#xff0c;更简单且具有前瞻性的方法则是采用原生分布式数据库来解决扩展性问题。在这种规模化场景的…