springboot实现数据脱敏

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.mfbz.cn/a/193357.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【Java Spring】SpringBoot Bean详解

文章目录 1、Bean方法注解简介2、Bean注解重命名3、对象装配&#xff08;获取Bean对象&#xff09;3.1 对象装配之属性注入3.2 对象装配之Set 注入3.3 对象装配之构造方法注入 4、Resource VS Autowired5、Bean对象的作用域5.1 验证Bean对象的默认作用域5.2 Bean对象的六大作用…

openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态

文章目录 openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态132.1 背景信息132.2 前提条件132.3 操作步骤132.4 参数说明132.5 示例 openGauss学习笔记-132 openGauss 数据库运维-查看openGauss状态 132.1 背景信息 openGauss支持查看整个openGauss的状态&#…

自动驾驶学习笔记(十一)——高精地图

#Apollo开发者# 学习课程的传送门如下&#xff0c;当您也准备学习自动驾驶时&#xff0c;可以和我一同前往&#xff1a; 《自动驾驶新人之旅》免费课程—> 传送门 《Apollo Beta宣讲和线下沙龙》免费报名—>传送门 文章目录 前言 高精地图 地图采集 底图制作 地图…

FLASK博客系列4——再谈路由

最近好像拖更有点久了。抱歉抱歉~ 今天我们继续来聊聊路由&#xff08;其实就是我上次偷懒剩下一点没讲完&#xff09;。 通过上次的文章&#xff0c;我们基本了解了Flask中的路由&#xff0c;是不是比较简单呢&#xff1f;别急&#xff0c;今天来点猛料。 一、路由之HTTP方法绑…

1233:单词倒置(C语言)

题目描述 最近birdfly收到了女友的几份信件&#xff0c;为了只要他俩知道信件的秘密&#xff0c;女友把信件里的每个单词都倒置了。这样只有birdfly将它们倒置过来才能明白女友的心思了。为此birdfly还特意请你编写程序帮他解决一下这个问题。 简单起见假定每封信只包含英文单词…

B 树和 B+树 的区别

文章目录 B 树和 B树 的区别 B 树和 B树 的区别 了解二叉树、AVL 树、B 树的概念 B 树和 B树的应用场景 B 树是一种多路平衡查找树&#xff0c;为了更形象的理解。 二叉树&#xff0c;每个节点支持两个分支的树结构&#xff0c;相比于单向链表&#xff0c;多了一个分支。 …

Android aidl的简单使用

一.服务端 1.创建aidl文件&#xff0c;然后记得build下生成java文件 package com.example.aidlservice31;// Declare any non-default types here with import statementsinterface IMyAidlServer {// 接收一个字符串参数void setData(String value);// 返回一个字符串String …

地理坐标系转换

1.EPSG代码 搜索地理坐标系对应的EPSG代码 https://epsg.io/ 常用的地理坐标系EPSG代码&#xff1a; 2. 坐标系转换 转换网址&#xff1a; https://epsg.io/transform &#xff08;1&#xff09;修改 input coordinate system 和 output coordinate system&#xff0c; 可以…

P19 C++ 构造函数的成员初始化列表

目录 前言 01 如果不用成员列表如何初始化变量 02 成员列表初始化 03 为什么要使用成员列表初始化呢&#xff1f; 04 案例代码 前言 本期我们聊聊构造函数初始化列表。 你应该经常使用成员初始化列表&#xff0c;如果你不喜欢这种代码风格&#xff0c;建议你还是慢慢习惯吧…

大导演王晶进军短剧,小程序短剧质量再上一层,短剧小程序的

在2023年11月26号&#xff0c;大导演王晶在横店进行开机仪式&#xff0c;短剧《亿万傻儿子》开拍&#xff0c;该短剧题材为都市、男频。 目前短剧是比较热门&#xff0c;大导演王晶拍摄短剧可谓是将短剧的质量提高一个层次。 侧面反映了短剧已经是非常广泛了。后续发展就是哪家…

Aapche Dubbo 不安全的 Java 反序列化 (CVE-2019-17564)

漏洞描述 Apache Dubbo 是一个高性能的、基于 Java 的开源 RPC 框架。 Apache Dubbo 支持不同的协议&#xff0c;它的 HTTP 协议处理程序是 Spring Framework 的 .org.springframework.remoting.httpinvoker.HttpInvokerServiceExporter Spring Framework 的安全警告显示&am…

ProFTPD-1.3.3c Backdoor Command Execution漏洞复现+poc

https://www.whereisk0shl.top/post/proftpd-1.3.3chou-men-fen-xi https://github.com/proftpd/proftpd 在官网和官方github上找了一圈1.3.3c版本的proftpd&#xff0c;应该是漏洞太多&#xff0c;官方把下了 https://blog.csdn.net/morrino/article/details/115836400 这个文…

ssm+vue的公司安全生产考试系统(有报告)。Javaee项目,ssm vue前后端分离项目。

演示视频&#xff1a; ssmvue的公司安全生产考试系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;ssm vue前后端分离项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结…

Huggingface 超详细介绍

Hugging face 起初是一家总部位于纽约的聊天机器人初创服务商&#xff0c;他们本来打算创业做聊天机器人&#xff0c;然后在github上开源了一个Transformers库&#xff0c;虽然聊天机器人业务没搞起来&#xff0c;但是他们的这个库在机器学习社区迅速大火起来。目前已经共享了超…

AI 绘画 | Stable Diffusion 提示词扩展插件

前言 提示词对于Stable Diffusion AI绘画来说非常重要, 由于Stable Diffusion 支持英文提示词,对于英文不好的朋友,每次都要切换翻译网站去翻译,很不方便,下面介绍两款Stable Diffusion 提示词扩展插件,让你写提示词更轻松。 sd-webui-prompt-all-in-one 提示词多合一插…

d3dx9_39.dll丢失问题及其解决方法,3分钟快速搞定d3dx9_39.dll文件

d3dx9_39.dll丢失你们都遇到过么&#xff1f;其实这个dll文件的丢失&#xff0c;一般是喜欢玩游戏的朋友会经常遇到的&#xff0c;小编觉得很有必要来给大家详细的说一下这方面的事情&#xff0c;教大家关于d3dx9_39.dll丢失问题及其解决方法&#xff0c;好了&#xff0c;我们废…

区块链存证:杭州互联网法院备选方案之一

文章目录 背景上报的存证系统设计备选方案***总体原则******分层架构******基础节点******存证链******存证业务******存证接入******通用功能******跨链对接架构***业务流程描述用户发起原创内容存证&#xff08;对应上图中左边1,2,3活动&#xff09;发现侵权行为&#xff0c;…

Echart力引导依赖关系布局图

Echarts ECharts&#xff08;Enterprise Charts&#xff09;Apache ECharts是百度开发的一款开源的 JavaScript 数据可视化库。它提供了丰富的图表和图形&#xff0c;适用于在 Web 应用程序中创建各种交互式和动态的数据可视化图表。ECharts支持各种图表类型&#xff0c;包括折…

云平台系列:What is Serverless (FaaS、BaaS)

文章目录 前言IaaS 与 PaaS 和SaaSIaaS&#xff08;基础设施即服务&#xff09;PaaS&#xff08;平台即服务&#xff09;SaaS&#xff08;软件即服务&#xff09;聊聊 IaaS What is Serverless?FaaS&#xff08;函数即服务&#xff09;执行适应场景 BaaS&#xff08;后端即服务…

OCR常用数据集_看数据集区分可识别语言

这里写目录标题 COCO-TEXT 英文Total-Text 英文少量中文IIIT5K[50]、IC03[44]、IC13[34]、IC15[33]、CT80[56]MJSynth 英文SynthText分层文本数据集 (HierText) 英文TextOCR和IntelOCR &#xff1f;&#xff1f;&#xff1f;Multi-language dataset (IC19)RCTW17 主要中文MSRA-…
最新文章