在Springboot中创建自定义Jasypt PropertySource

 用户691sf34d0b 发布于 2023-01-07 13:13

我正在使用Spring Boot创建一个访问数据库的简单Web应用程序.我通过设置spring.datasource.*属性来利用DataSource的自动配置功能application.properties.这一切都很出色,非常快 - 很棒的工作人员@Spring!

我公司的政策是不应该有明文密码.因此我需要sping.datasource.password加密.经过一番挖掘后,我决定创建一个org.springframework.boot.env.PropertySourceLoader实现,创建一个jasypt org.jasypt.spring31.properties.EncryptablePropertiesPropertySource如下:

public class EncryptedPropertySourceLoader implements PropertySourceLoader
{
    private final StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();

    public EncryptedPropertySourceLoader()
    {
        //TODO: this could be taken from an environment variable
        this.encryptor.setPassword("password"); 
    }

    @Override
    public String[] getFileExtensions()
    {
        return new String[]{"properties"};
    }

    @Override
    public PropertySource load(final String name, final Resource resource, final String profile) throws IOException
    {
        if (profile == null)
        {
            final Properties props = PropertiesLoaderUtils.loadProperties(resource);

            if (!props.isEmpty())
            {
                return new EncryptablePropertiesPropertySource(name, props, this.encryptor);
            }
        }

        return null;
    }
}

然后我将它打包在它自己的jar中,META-INF/spring.factories文件如下:

org.springframework.boot.env.PropertySourceLoader=com.mycompany.spring.boot.env.EncryptedPropertySourceLoader

从maven运行时,这非常有效mvn spring-boot:run.当我将其作为独立的战争使用时,会出现问题java -jar my-app.war.当我尝试连接到数据库时,应用程序仍然加载但失败,因为密码值仍然是加密的.添加日志记录显示EncryptedPropertySourceLoader永远不会加载.

对我来说这听起来像是一个类路径问题.在maven下运行时,jar加载顺序是严格的,但是一旦在嵌入的tomcat下,没有什么可说的,我的自定义jar应该在Spring Boot之前加载.

我已经尝试将以下内容添加到我的pom.xml中以确保保留classpth但它似乎没有任何影响.


    
        
            
                org.apache.maven.plugins
                maven-war-plugin
                
                    false
                    
                        
                            ${start-class}
                            true
                        
                    
                
            
        
    
    
        
            org.springframework.boot
            spring-boot-maven-plugin
        
    

有没有人有任何想法?提前致谢.

更新:

向前迈出的一步:我已经设法通过让EncryptedPropertySourceLoader类实现org.springframework.core.PriorityOrdered接口并HIGHEST_PRECEDENCE从中返回来解决这个问题getOrder().这已经解决了未使用PropertySourceLoader的问题.但是,当它尝试解密属性时,它现在抛出以下错误:

org.jasypt.exceptions.EncryptionInitializationException: java.security.NoSuchAlgorithmException: PBEWithMD5AndDES SecretKeyFactory not available
    at org.jasypt.encryption.pbe.StandardPBEByteEncryptor.initialize(StandardPBEByteEncryptor.java:716)
    at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.initialize(StandardPBEStringEncryptor.java:553)
    at org.jasypt.encryption.pbe.StandardPBEStringEncryptor.decrypt(StandardPBEStringEncryptor.java:705)
    at org.jasypt.properties.PropertyValueEncryptionUtils.decrypt(PropertyValueEncryptionUtils.java:72)
    at org.jasypt.properties.EncryptableProperties.decode(EncryptableProperties.java:230)
    at org.jasypt.properties.EncryptableProperties.get(EncryptableProperties.java:209)
    at org.springframework.core.env.MapPropertySource.getProperty(MapPropertySource.java:36)
    at org.springframework.boot.env.EnumerableCompositePropertySource.getProperty(EnumerableCompositePropertySource.java:49)
    at org.springframework.boot.context.config.ConfigFileApplicationListener$ConfigurationPropertySources.getProperty(ConfigFileApplicationListener.java:490)

同样,这在运行时不会发生,mvn spring-boot:run但在从可执行war文件运行时确实发生.两种方案都使用相同的JVM(jdk1.6.0_35).Google/Stackoverflow上的结果表明这是java安全策略的一个问题,但是当它从maven运行时确实有效,我想我可以打折.可能是包装问题......

2 个回答
  • 你可以尝试一下:jasypt-spring-boot 它基本上用环境包装加密版本中存在的所有PropertySource.导入库后要做的两件事(如果使用maven则添加依赖关系)是使用@EnableEncryptableProperties注释@Configuration类,并通过属性配置加密算法和密码.

    2023-01-07 13:16 回答
  • 这里有两个问题.

    1)需要加载EncryptedPropertySourceLoader高于标准的PropertiesPropertySourceLoader.这可以通过实现PriorityOrder接口来实现,如下所示:

    public class EncryptedPropertySourceLoader implements PropertySourceLoader, PriorityOrdered
    {
        private final StandardPBEStringEncryptor encryptor = new StandardPBEStringEncryptor();
    
        public EncryptedPropertySourceLoader()
        {
            this.encryptor.setPassword("password"); //TODO: this could be taken from an environment variable
        }
    
        @Override
        public String[] getFileExtensions()
        {
            return new String[]{"properties"};
        }
    
        @Override
        public PropertySource<?> load(final String name, final Resource resource, final String profile) throws IOException
        {
            if (profile == null)
            {
                //load the properties
                final Properties props = PropertiesLoaderUtils.loadProperties(resource);
    
                if (!props.isEmpty())
                {
                    //create the encryptable properties property source
                    return new EncryptablePropertiesPropertySource(name, props, this.encryptor);
                }
            }
    
            return null;
        }
    
        @Override
        public int getOrder()
        {
            return HIGHEST_PRECEDENCE;
        }
    }
    

    org.springframework.core.io.support.SpringFactoriesLoader其加载类org.springframework.boot.env.PropertySourceLoaderMETA-INF/spring.factories结果采用订单org.springframework.core.OrderComparator.这意味着应该首先返回此类,并且将负责为*.proerpties文件提供PropertySourceLoader实现.

    2)第二个是可执行JAR/WAR的类加载问题,这似乎是由Windows上的Spring Boot 1.1.2.RELEASE版本中的错误引起的.删除版本1.1.1.RELEASE或版本1.1.3.RELEASE解决了在maven外部运行时没有加载类和proerpties文件的各种问题.

    2023-01-07 13:17 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有