Springboot 配置文件脱敏的实践

news/2025/2/6 4:06:51/

写作目的

数据安全这块还是挺严重的,尤其是自己专注于业务开发,不能总停留在一个地方,还要关注其他的一些问题,比如数据安全。

配置脱敏

实现配置的脱敏我使用了Java的一个加解密工具Jasypt。该工具支持对称加密和非对称加密。
首先通过简单的demo配置进行配置和测试。

1、首先引入jasypt-spring-boot-starter

<!--配置文件加密--><dependency><groupId>com.github.ulisesbocchio</groupId><artifactId>jasypt-spring-boot-starter</artifactId><version>2.1.0</version></dependency>

2、接下来就是application的配置,如下面代码所示。其中password是密钥,即类似于MD5盐值加密的盐;prefixsuffix*为判断要解密的规则条件或正则表达式

jasypt:encryptor:password: demo   # 秘钥property:prefix: "abc["  #前缀suffix: "]"     #后缀

3、配置好后我们就需要在配置文件中配置加密后的数据了,如下面的数据库密码

spring:datasource:url: jdbc:mysql://localhost:3306/demo?characterEncoding=utf8&useUnicode=true&useSSL=false&serverTimezone=GMT%2B8username: rootpassword: abc[B6jeXwl1AotiulW1vfsKmQ==]   ### 前缀和后缀包围着密文driver-class-name: com.mysql.cj.jdbc.Drivertype: com.alibaba.druid.pool.DruidDataSource

那么这串密文是怎么来的呢?

    System.out.println("--------------加密----------------");StandardPBEStringEncryptor standardPBEStringEncryptor = new StandardPBEStringEncryptor();// 秘钥standardPBEStringEncryptor.setPassword("demo");// 明文进行加密String code = standardPBEStringEncryptor.encrypt("123456");System.out.println(code);System.out.println("--------------解密----------------");// 解密String decrypt = standardPBEStringEncryptor.decrypt(code);System.out.println(decrypt);

结果为
在这里插入图片描述

4、接下来就是启动项目了。

整个配置文件脱敏的配置就算完成了。其实就是两步。配置jasypt的密钥、前缀和后缀等信息;获取加密后的数据(如本文中的数据库密码信息)

脱敏原理

添加BeanFactoryPostProcessor

既然是以springboot方式集成,那么就先从jasypt-spring-boot-starter源码开始入手。该starter中会有一个spring.factories文件,文件中会配置自动装配的类,即JasyptSpringBootAutoConfiguration
该类又通过Import注解引入了EnableEncryptablePropertiesConfiguration

其中EnableEncryptablePropertiesConfiguration主要向ioc容器中注入了一个EnableEncryptablePropertiesBeanFactoryPostProcessor,其中一个参数为environment,如下图所示,我们只要把这个类搞明白就理解核心了。
在这里插入图片描述

该BeanFactoryPostProcessor的目的

那么EnableEncryptablePropertiesBeanFactoryPostProcessor是什么呢?那就要看他实现的接口,该类实现了BeanFactoryPostProcessor接口,那么我们有理由去看postProcessBeanFactory方法(Spring的生命周期知识点)。
在postProcessBeanFactory方法里,该方法的主要逻辑为获取environment的propSources并进行convert转换,如下图所示。
在这里插入图片描述

propSources是什么?

propSources其实是环境变量文件或者配置文件的集合。如下图所示。我们直接下标为6的元素里的数据,其实可以发现下标为6的元素对应的就是我们的application.yml
在这里插入图片描述
其实EnableEncryptablePropertiesBeanFactoryPostProcessor获取上述的环境变量文件或者配置文件的数据也可以理解,毕竟你需要对里面的数据进行加密和解密,你不拿到数据怎么加密和解密呢?

convert动作的逻辑是什么?

convert的代码如下图所示,对于propSources里的每一个元素ps,都通过makeEncryptable方法转换为一个新的对象,并替换掉原来的ps
在这里插入图片描述
那么makeEncryptable方法是怎么替换的?一直跟上面的convert最后到了下图中的方法。其实就是把propertySource对象进行包装Wrapper,然后替换掉原来的propertySource对象。
在这里插入图片描述
当我们想获取某个配置文件中的kv时,再调用getProperty时其实已经走EncryptablePropertySourceWrapper的getProperty方法了(因为上面被替换了)。

获取配置文件的kv进行过滤和解密

当然经过各种实现类和实现类里依赖的其他接口的实现类,最后getProperty的方法会到下面的方法里,如下面代码所示,其实就是先在原始source获取数据,然后判断是否需要解密,需要的话就直接把解密后的数据返回,完美了。

#EncryptablePropertySourcedefault Object getProperty(EncryptablePropertyResolver resolver, EncryptablePropertyFilter filter, PropertySource<T> source, String name) {Object value = source.getProperty(name);if (filter.shouldInclude(source, name) && value instanceof String) {String stringValue = String.valueOf(value);return resolver.resolvePropertyValue(stringValue);}return value;}

总结

注册一个BeanFactoryPostProcessor
在postProcessBeanFactory方法里对propSources进行包装为propSourcesWrapper
在获取配置文件时对propSourcesWrapper进行获取数据,当符合解密规则时进行解密

参考

Springboot 配置文件、隐私数据脱敏的最佳实践(原理+源码)


http://www.ppmy.cn/news/100542.html

相关文章

c++—模板(函数模板、类模板)

1. 模板是解决代码复用的最优解&#xff0c;其原理是为功能不变而参数数据类型不同的的程序提供一种代码共享机制&#xff0c;模板也是一种多态的实现&#xff0c;可以在编译器协助开发者生成代码&#xff0c;从而演化为面向模板元编程&#xff08;面向编译器&#xff09;&…

CAPL(vTESTStudio) - CAPL控制程控电源IT6332A

目录 为什么要使用CAPL控制程控电源? 一、程控电源的选择 二、程控电源通信协议

整型在内存中的存储,整型最大值最小值的推导,以及大小端的介绍

整数在内存中的存储 我们知道C语言有以下基本的整型类型&#xff1a; char //字符型 short //短整型 int //整型 long //长整型 long long //更长的整型我们可以用操作符sizeof和在<limits.h>头文件下&#xff0c;可以查看到各基本数据类型的所占字节的大小以及整形所…

Kubernetes_核心组件_kubelet_kubelet服务全解析

文章目录 前言一、查看kubelet当前运行1.1 查看kubelet当前运行1.2 kubelet配置文件1.3 kubelet启动参数文件1.4 kubelet启动全过程 (自定义启动参数文件) 二、kubelet启动过程2.1 kubelet启动过程2.2 自定义kubelet所有文件并运行步骤1&#xff1a;新建静态token文件和user&am…

在 Git 中撤消更改的 6 种方法!

目录 1. 修改最近的提交 2. 将分支重置为较旧的提交 硬重置 软重置分支 创建备份分支 3. 交互式变基 删除旧提交 改写提交消息 编辑旧提交 压缩 4. 还原提交 5. 签出文件 6. 使用 Git Reflog 当使用 Git 进行项目代码管理时&#xff0c;难免会出现一些错误操作或需…

list常见接口的使用(基于c++标准库中的STL)

前言 list是重要的容器了解它的常见接口以及使用是很有必要的&#xff0c;为什么有了vector还要有list呢&#xff1f;因为vector存在一些缺陷&#xff0c;比如&#xff1a;容量满了要扩容&#xff0c;扩容是要付出代价的&#xff08;性能的损失&#xff09;&#xff0c;存在空…

任务7 课程信息管理系统

系列文章 任务7 课程信息管理系统 已知课程的信息包括&#xff1a;课程编号&#xff0c;课程名称&#xff0c;课程性质&#xff08;必修、选修&#xff09;&#xff0c;课时&#xff0c;学分&#xff0c;考核方式&#xff08;考试、考查课&#xff09;&#xff0c;开课学期&a…

DIP:依赖反转原则

系列文章目录 C高性能优化编程系列 深入理解设计原则系列 深入理解设计模式系列 高级C并发线程编程 DIP&#xff1a;依赖反转原则 系列文章目录1、依赖反转原则的定义和解读2、稳定的抽象层3、依赖倒置原则和控制反转、依赖注入的联系小结 1、依赖反转原则的定义和解读 SOIL…