springboot实现数据脱敏

news2024/11/25 16:41:52

springboot实现数据脱敏

  • 怎么说呢,写着写着发觉 ”这写的什么玩意“ 。

    总的来说就是,这篇文章并不能解决数据脱敏问题,但以下链接可以

    SpringBoot中利用自定义注解优雅地实现隐私数据脱敏

    然后回到本文,本来是想基于AOP代理,实现返回数据脱敏的,具体流程是:

    1. 在controller做切面,实现返回通知

    2. 返回通知中获取返回值对象

    3. 利用反射获取返回值字段

    4. 标有脱敏注释的字段做脱敏处理

    说着好像一套一套的,但事实上,忽略了一个重要的问题,复杂对象很难做反射,例如集合List,Set,Map,或者对象的引用也是对象,就算用多重判断深度遍历,但是反射带来的耗时以及空间开销都是值得思考的,总而言之,这是一个很low的方案。

    但是我很少用到反射,并且感觉既然都写到这了,不如记录一下,aop和反射结合,以后可能会用来实现其他有趣的功能也说不定。那就记录一下吧。

1. 引入依赖

        <!-- 引入aop支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

2. 实现两个注解

一个标注在controller方法上,Service也可以

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DesensitizeResult {
    
}

一个标注在属性上

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DesensitizeField {

    // 字段名称,给字段起个名字而已,没啥用
    String name() default "字段名";

    // 前面正常显示字符长度(不脱敏长度)
    int prefixShow() default 1;

    // 后面正常显示字符长度(不脱敏)长度
    int suffixShow() default 0;

    // 脱敏引用符号
    String symbol() default "*";
}

3. 编写切面方法类

@Aspect
@Component
public class DesensitizeAspect {

    @Pointcut("@annotation(com.example.testdemo.annotation.DesensitizeResult)")
    public void getDesensitizeAnno(){}

    /**
     * 返回贴面编程,对返回结果result做脱敏操作
     * @param joinPoint 切点
     * @param result 目标方法返回结果
     */
    @AfterReturning(pointcut = "getDesensitizeAnno()",returning = "result")
    public void afterReturn(JoinPoint joinPoint,Object result){
        // 获取返回结果类的所有属性数组
        Class resultClass = result.getClass();
        Field[] declaredFields = resultClass.getDeclaredFields();
        for (Field field : declaredFields){
            // 循环判断属性中是否存在自定义脱敏注解@DesensitizeField
            for (Annotation annotation : field.getAnnotations()) {
                Class<? extends Annotation> aClass = annotation.annotationType();
                if (aClass.equals(DesensitizeField.class)){
                    DesensitizeField desensitizeField = (DesensitizeField) annotation;
                    // 对标有@DesensitizeField的属性进行脱敏处理
                    field.setAccessible(true);      // 先将该属性改为允许值修改
                    try {
                        String originStr = (String)field.get(result);   // 获取原来的值
                        // 字符串脱敏
                        String desensitizeValue = this.desensitizeStr(originStr, desensitizeField.prefixShow(),
                                desensitizeField.suffixShow(), desensitizeField.symbol());
                        field.set(result,desensitizeValue); // 将脱敏后的字符串写入
                    } catch (IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        }
    }

    /**
     * 
     * @param originStr 原字符串
     * @param prefixShow 前置正常字符串长度
     * @param suffixShow 后置正常字符串长度
     * @param symbol 脱敏字符显示标志
     * @return 脱敏后字符串
     */
    private String desensitizeStr(String originStr, int prefixShow, int suffixShow, String symbol){
        int length = originStr.length();
        // 避免out of index
        prefixShow = Math.min(prefixShow, length);
        suffixShow = Math.min(suffixShow,length);
        // 前后显示数据超过数据是指长度处理,OutOfRange处理
        if (prefixShow+suffixShow>length){
            prefixShow=length;
            suffixShow=0;
        }
        String desensitizeValue = originStr.substring(0,prefixShow)
                +symbol.repeat(length-prefixShow-suffixShow)
                +originStr.substring(length-suffixShow);
        return desensitizeValue;
    }

}

如上代码所示,只是针对单个简单对象做字段脱敏,复杂对象就完了

4. 测试实体类

@Data
@ToString
public class UserInfo {

    private String id;
    private String account;
    private String nickname;
    @DesensitizeField(name = "真实姓名",prefixShow = 1)
    private String realName;
    @DesensitizeField(name = "密码",prefixShow = 0)
    private String password;
    @DesensitizeField(name = "手机号",prefixShow = 3,suffixShow = 1)
    private String mobile;
    @DesensitizeField(name = "身份证号",prefixShow = 3)
    private String identityId;
    private String createTime;

}

5. 测试接口

@RestController
public class TestController {
    @DesensitizeResult  // aop切面脱敏数据
    @GetMapping("/userInfo")
    public UserInfo getUserInfo(){
        UserInfo userInfo = new UserInfo();
        userInfo.setId("123456");
        userInfo.setAccount("abcdef");
        userInfo.setMobile("13579246810");
        userInfo.setNickname("BigBoss");
        userInfo.setRealName("张小凡");
        userInfo.setIdentityId("430121200001011321");
        userInfo.setPassword("Mm123456#");
        return userInfo;
    }
}

6.测试

image-20231127195103232.png

至此,全文完毕,另外盘算着下次把上面链接的方案偷过来再发一篇。

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

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

相关文章

MySQL优化技巧

在使用一些常规的 SQL 时&#xff0c;如果我们通过一些方法和技巧来优化这些 SQL 的实现&#xff0c;在性能上就会比使用常规通用的实现方式更 优化分页查询 通常我们是使用 <LIMIT M,N> 合适的 order by 来实现分页查询&#xff0c;这种实现方式在没有任何索引条件支…

【Java】IDEA 基本操作

0.IDEA 0.1 IDEA中的层级结构 0.1.1 结构分类 project&#xff08;项目、工程&#xff09;module&#xff08;模块&#xff09;package&#xff08;包&#xff09;class&#xff08;类&#xff09; 0.1.2 结构介绍 project&#xff08;项目、工程&#xff09; ​ 淘宝、京…

物联网AI 无线连接学习之WiFi基础篇 802.11协议发展

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 前言 随着物联网行业不断发展&#xff0c;WiFi技术的发展在其中起着非常关键的作用&#xff0c;也是我们日常生活中使用非常广泛的无线网络技术之一&#xff0c;现在我们随便买一个家用电子产品&#xff0c…

java springboot测试类Transactional解决 测试过程中在数据库留下测试数据问题

好 目前 我们已经完成了表现层对应的测试了 但这里有个坑 如果我们在执行某个声明周期时 包含了测试的过程 它会在数据库中留下一条数据 但真实企业开发 绝对不允许 过一遍留一组数据的 那么 我们的期望就是 执行测试过程 但不要留下任何数据 这是我们的数据库表 然后 这里…

华为电视盒子 EC6108V9C 刷机成linux系统

场景&#xff1a; 提示&#xff1a;这里简述项目相关背景&#xff1a; 家里装宽带的时候会自带电视盒子&#xff0c;但是由于某些原因电视盒子没有用&#xff0c;于是就只能摆在那里吃土&#xff0c;闲来无事&#xff0c;搞一下 问题描述 提示&#xff1a;这里描述项目中遇到…

zi定义指令

hello&#xff0c;我是小索奇&#xff0c;精心制作的Vue系列持续发放&#xff0c;涵盖大量的经验和示例&#xff0c;如果对您有用&#xff0c;可以点赞收藏哈~ 自定义指令 自定义指令就是自己定义的指令&#xff0c;是对 DOM 元素进行底层操作封装 ,程序化地控制 DOM&#xff…

医院电子病历编辑器源码(支持云端SaaS服务)

电子病历系统基于云端SaaS服务的方式&#xff0c;采用B/S&#xff08;Browser/Server&#xff09;架构提供&#xff0c;采用前后端分离模式开发和部署。使用用户通过浏览器即能访问&#xff0c;无需关注系统的部署、维护、升级等问题&#xff0c;系统充分考虑了模板化、 配置化…

Linux操作系统使用及C高级编程-D17D18编译与调试

编译 当有线程创建时编译&#xff1a;gcc test.c -o test -lpthread 分文件编写时主要是分为&#xff1a;.c&#xff08;函数声明的具体实现&#xff09;、.h&#xff08;说明性文件&#xff1a;#define 结构体共用体 声明&#xff09;、.c(main) 条件编译 一般情况下&#x…

【Linux】初识重定向(输入输出)

一切皆文件 这是Linux的设计理念&#xff0c;因为这个理念的存在我们可以使用统一的方法对待不同的东西&#xff0c;&#xff0c;这也是为什么嵌入式之类的会需要Linux&#xff0c;因为用LInux来操纵硬件真的很方便 另外我们下文也会都基于这个理念来命名&#xff0c; 比如&am…

用做Excel的思维去做BI报表,大材小用了!

最近看到一个姐妹吐槽说公司上了BI后&#xff0c;反而没有以前Excel用得顺手了。这不可能&#xff0c;这不科学&#xff01;怀着求知心点进去一看&#xff0c;这位姐妹居然是在用做Excel的思维去做BI报表&#xff0c;这就很难评了&#xff01; Excel和BI报表&#xff0c;那是两…

MSTP实验

目录 一、实验拓扑 二、实验要求 三、实验步骤 1、创建vlan 2、创建端口组&#xff0c;放通vlan 3、配置MSTP 4、配置主备奋根 一、实验拓扑 二、实验要求 1、所有交换机上创建vlan10&#xff0c;vlan20&#xff0c;vlan30和vlan40 2、所有交换机之间的端口配置为Trunk…

【斗破年番】萧炎斩杀蝎山,活捉魂殿铁护法,救小医仙身中魔斑毒

Hello,小伙伴们&#xff0c;我是拾荒君。 《斗破苍穹年番》第72集的国漫已经更新了。这一集中&#xff0c;蝎毕岩靠着秘术的加成暂时压制住了小医仙。在激烈的交战中&#xff0c;小医仙不得不解开自身的厄难毒体&#xff0c;而每解开一次&#xff0c;她就离死亡更近一步。 萧炎…

java--子类构造器的特点

1.子类构造器的特点 子类的全部构造器&#xff0c;都会先调用父类的构造器&#xff0c;再执行自己。 2.子类构造器是如何实现调用父类构造器的 ①默认情况下&#xff0c;子类全部构造器的第一行代码都是super()(写不写都有)&#xff0c;它会调用父类的无参数构造器。 ②如果…

EfficientViT:具有级联群体注意力的内存高效Transformer

EfficientViT: Memory Efficient Vision Transformer with Cascaded Group Attention 1、介绍2、使用 Vision Transformer 加快速度2.1 内存效率2.2 计算效率2.3 参数效率 3、Efficient Vision Transformer3.1 EfficientViT 构建模块3.3 EfficientViT 网络架构 4、实验5、结论 …

什么是可重入锁

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一份大厂面试资料《史上最全大厂面试题》&#xff0c;Springboot、微服务、算法、数据结构、Zookeeper、Mybatis、Dubbo、linux、Kafka、Elasticsearch、数据库等等 …

给国外客户价格报低了怎么办

前一段时间有一个单子的货发出去了&#xff0c;被朋友提醒才发现自己报错了价格&#xff0c;造成了亏损&#xff0c;而报错价格的原因并不是自己看错了或者是抄错了价格&#xff0c;而是自己的脑子里记错了产品的价格列表。 如果不是朋友善意的提醒&#xff0c;大概我会一直错…

Current request is not a multipart request问题排查

概述 在应用工程里看到如下被标记为deprecated的代码&#xff0c;这对有代码洁癖的我而言是无法忍受的&#xff1a; row.getCell(10).setCellType(Cell.CELL_TYPE_STRING); String hospital row.getCell(0).getStringCellValue();对应的poi版本号&#xff1f;是的&#xff…

基本数据结构二叉树(2)

目录 3.二叉树的顺序结构及实现 3.1 二叉树的顺序结构 3.2 堆的概念及结构 3.3 堆的实现 3.2.1 堆向下调整算法 3.2.2堆的创建 3.2.3 建堆时间复杂度 3.2.4 堆的插入 3.2.5 堆的删除 3.2.6 堆的代码实现 3.4 堆的应用 3.4.1 堆排序 3.4.2 TOP-K问题 3.二叉树的顺序…

陆正耀卖奶茶,是库迪不行了吗?

文 | 智能相对论 作者 | 胡静婕 咖啡还没“玩”明白&#xff0c;陆正耀又要开始卖奶茶了。 11月23日&#xff0c;陆正耀创立的库迪咖啡确认&#xff0c;其奶茶品牌“茶猫”系库迪咖啡旗下第二品牌&#xff0c;将于2024年1月正式上市&#xff0c;公司仍将采取风险共担的联营模…

软著项目推荐 深度学习中文汉字识别

文章目录 0 前言1 数据集合2 网络构建3 模型训练4 模型性能评估5 文字预测6 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习中文汉字识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xf…