【开源项目】SpringBoot之Jasypt实现配置文件加密解密

需求背景

数据库密码直接明文写在配置中,对安全来说,是一个很大的挑战。一旦密码泄漏,将会带来很大的安全隐患。尤其在一些企业对安全性要求很高,因此我们就考虑如何对密码进行加密。

快速入门

引入Maven

        <dependency>
            <groupId>com.github.ulisesbocchiogroupId>
            <artifactId>jasypt-spring-boot-starterartifactId>
            <version>3.0.4version>
        dependency>

配置文件

jasypt:
  encryptor:
    algorithm: PBEWithMD5AndDES
    # jasypt加密的盐值
    password: 123456
    iv-generator-classname: org.jasypt.iv.NoIvGenerator

spring:
  # 数据库配置
  datasource:
#    driver-class-name: com.mysql.cj.jdbc.Driver
    url: ENC(W+vcCn52uIhTRfwf++D3H1BSjwgAfUvmgzC4ksV5hqjRQrXpFzL5tNKzf6Tpj42kTrlycDr5//wi4jmb+wKrqZGCH2vrcRluP92CH827bJK66qnoUUXVp4UlvC/qYaOFvI/UNWIQUX3SlIUBi5eNA/qS8YWQAxcoBbMQ3qRWTa85il2Ue0vjhF4X7VlNF9LkXXbz9GYhU0g=)
    username: ENC(zJI0GE9ZpOJjuaRjk2B9uA==)
    password: ENC(a/kikxloS7NP34jJLgu3ng==)

解密

@RestController
public class TestController {

    @Value("${spring.datasource.url}")
    private String dsUrl;

    @GetMapping("/test")
    public String getData() {
        System.out.println(dsUrl);
        return dsUrl;
    }
}

源码解析

  • jaspcry-spring-boot-starter的jar包中找到自动装配的入口:spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.ulisesbocchio.jasyptspringbootstarter.JasyptSpringBootAutoConfiguration

org.springframework.cloud.bootstrap.BootstrapConfiguration=com.ulisesbocchio.jasyptspringbootstarter.JasyptSpringCloudBootstrapConfiguration

JasyptSpringBootAutoConfiguration加载配置类EnableEncryptablePropertiesConfiguration

@Configuration
@Import({EnableEncryptablePropertiesConfiguration.class})
public class JasyptSpringBootAutoConfiguration {
    public JasyptSpringBootAutoConfiguration() {
    }
}

EnableEncryptablePropertiesConfiguration加载bean工厂后置处理类,EnableEncryptablePropertiesBeanFactoryPostProcessor

@Configuration
@Import({EncryptablePropertyResolverConfiguration.class, CachingConfiguration.class})
@Slf4j
public class EnableEncryptablePropertiesConfiguration {

    @Bean
    public static EnableEncryptablePropertiesBeanFactoryPostProcessor enableEncryptablePropertySourcesPostProcessor(final ConfigurableEnvironment environment, EncryptablePropertySourceConverter converter) {
        return new EnableEncryptablePropertiesBeanFactoryPostProcessor(environment, converter);
    }
}

EnableEncryptablePropertiesBeanFactoryPostProcessor#postProcessBeanFactory,主要是将所有的PropertySource都转换成了EncryptablePropertySource

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        log.info("Post-processing PropertySource instances");
        MutablePropertySources propSources = environment.getPropertySources();
        converter.convertPropertySources(propSources);
    }

重写了获取配置信息的接口,EncryptablePropertySource#getProperty()

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

DefaultPropertyResolver#resolvePropertyValue,判断是否加密了,如果加密进行解密操作。

    public String resolvePropertyValue(String value) {
        return Optional.ofNullable(value)
                .map(environment::resolvePlaceholders)
                .filter(detector::isEncrypted)
                .map(resolvedValue -> {
                    try {
                        String unwrappedProperty = detector.unwrapEncryptedValue(resolvedValue.trim());
                        String resolvedProperty = environment.resolvePlaceholders(unwrappedProperty);
                        return encryptor.decrypt(resolvedProperty);
                    } catch (EncryptionOperationNotPossibleException e) {
                        throw new DecryptionException("Unable to decrypt property: " + value + " resolved to: " + resolvedValue + ". Decryption of Properties failed,  make sure encryption/decryption " +
                                "passwords match", e);
                    }
                })
                .orElse(value);
    }

【开源项目】SpringBoot之Jasypt实现配置文件加密解密_第1张图片

你可能感兴趣的:(开源项目介绍,spring,boot,开源,java)