参考认识BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor - 知乎
SpringBoot 之 Jasypt 实现yml配置文件加密_-djasypt.encryptor.password-CSDN博客
【springboot】jasypt加密_jasypt.encryptor.password-CSDN博客
实现:
导包:
使用说明参考GitHub - ulisesbocchio/jasypt-spring-boot: Jasypt integration for Spring boot
<dependency>
<groupId>com.github.ulisesbocchio</groupId>
<artifactId>jasypt-spring-boot-starter</artifactId>
<version>3.0.4</version>
</dependency>
生成加密后的配置value:
public class EncryptionUtil {
//https://blog.csdn.net/qq_41055045/article/details/126740841
public static void main(String[] args) {
PooledPBEStringEncryptor encryptor = new PooledPBEStringEncryptor();
SimpleStringPBEConfig config = new SimpleStringPBEConfig();
// 加密方式
config.setAlgorithm("PBEWITHHMACSHA512ANDAES_256");
// 盐值
config.setPassword("salt");
config.setKeyObtentionIterations("1000");
config.setPoolSize("1");
config.setProviderName("SunJCE");
config.setSaltGeneratorClassName("org.jasypt.salt.RandomSaltGenerator");
config.setIvGeneratorClassName("org.jasypt.iv.RandomIvGenerator");
config.setStringOutputType("base64");
encryptor.setConfig(config);
// 加密明文
String encryptValue1 = encryptor.encrypt("root");
String encryptValue2 = encryptor.encrypt("root");
System.out.println(encryptValue1);
System.out.println(encryptValue2);
// 解密密文
String decryptValue = encryptor.decrypt("1B94SNKIuVmRNKeNmd2dkvAJTCilDPlof8l/FroMMYrH/nxXDf1OPdlUYkbBXB48");
System.out.println(decryptValue);
}
}
配置文件片段:
spring:
datasource:
primary:
jdbc-url: jdbc:postgresql://localhost:5432/test?characterEncoding=utf8&useSSL=true
username: postgres
password: ENC(76va5Nw3V+NjHHPh0Ekei7hwitxCAYCzEIpoJLYMOebc+VbCm66hYWm12+AWoKcO) #root
type: com.alibaba.druid.pool.DruidDataSource
hikari:
driver-class-name: org.postgresql.Driver
secondary:
jdbc-url: jdbc:sqlserver://localhost:1433;DatabaseName=test;Trusted_Connection=True
username: sa
password: ENC(H0MxJHbEiwXXiRp09UwEbU91HcNiufhAUTeIrptzW5vLllycbWodE0BgIxtDAoU7) #root
type: com.alibaba.druid.pool.DruidDataSource
hikari:
driver-class-name: com.microsoft.sqlserver.jdbc.SQLServerDriver
#参考
#https://zhuanlan.zhihu.com/p/653695574
#https://blog.csdn.net/qq_41617261/article/details/121448939
jasypt:
encryptor:
password: ${ENCRYPT:salt}
原理:
主要思路是实现了BeanFactoryPostProcessor,再装饰容器中原来的PropertySource类。
参考认识BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor - 知乎
BeanFactoryPostProcessor位于org.springframework.beans.factory.config包中。它与BeanPostProcessor有相似的核心逻辑,但它们之间的主要区别在于它们所操作的对象。BeanFactoryPostProcessor的主要目的是对Bean的配置元数据进行操作,这意味着它可以影响Bean的初始配置数据。
在Spring IoC容器实例化beans之前,特别是除了BeanFactoryPostProcessor之外的其他beans,BeanFactoryPostProcessor有权利修改这些beans的配置。在Spring中,所有的beans在被完全实例化之前都是以BeanDefinition的形式存在的。BeanFactoryPostProcessor为我们提供了一个机会,使我们能够在bean完全实例化之前调整和修改这些BeanDefinition。对BeanDefinition的任何修改都会影响后续的bean实例化和初始化过程。
源码解析:
package com.ulisesbocchio.jasyptspringboot.configuration;
import com.ulisesbocchio.jasyptspringboot.EncryptablePropertyResolver;
import com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
/**
* <p>{@link BeanFactoryPostProcessor} that wraps all {@link PropertySource} defined in the {@link Environment}
* with {@link com.ulisesbocchio.jasyptspringboot.wrapper.EncryptablePropertySourceWrapper} and defines a default {@link
* EncryptablePropertyResolver} for decrypting properties
* that can be configured through the same properties it wraps.</p>
* <p>
* <p>It takes the lowest precedence so it does not interfere with Spring Boot's own post processors</p>
*
* @author Ulises Bocchio
*/
@Slf4j
public class EnableEncryptablePropertiesBeanFactoryPostProcessor implements BeanFactoryPostProcessor, Ordered {
private final ConfigurableEnvironment environment;
private final EncryptablePropertySourceConverter converter;
public EnableEncryptablePropertiesBeanFactoryPostProcessor(ConfigurableEnvironment environment, EncryptablePropertySourceConverter converter) {
this.environment = environment;
this.converter = converter;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
log.info("Post-processing PropertySource instances");
MutablePropertySources propSources = environment.getPropertySources();//得到原始配置类,再做替换
converter.convertPropertySources(propSources);
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 100;
}
}
com.ulisesbocchio.jasyptspringboot.EncryptablePropertySourceConverter#makeEncryptable
方法内部得到PropertySource包装类 EncryptableMapPropertySourceWrapper内部封装了CachingDelegateEncryptablePropertySource,CachingDelegateEncryptablePropertySource内部封装了EncryptablePropertyResolver
public <T> PropertySource<T> makeEncryptable(PropertySource<T> propertySource) {
if (propertySource instanceof EncryptablePropertySource || skipPropertySourceClasses.stream().anyMatch(skipClass -> skipClass.equals(propertySource.getClass()))) {
if (!(propertySource instanceof EncryptablePropertySource)) {
log.info("Skipping PropertySource {} [{}", propertySource.getName(), propertySource.getClass());
}
return propertySource;
}
PropertySource<T> encryptablePropertySource = convertPropertySource(propertySource);
log.info("Converting PropertySource {} [{}] to {}", propertySource.getName(), propertySource.getClass().getName(),
AopUtils.isAopProxy(encryptablePropertySource) ? "AOP Proxy" : encryptablePropertySource.getClass().getSimpleName());
return encryptablePropertySource;
}

被折叠的 条评论
为什么被折叠?



