[英]Is there a way to make jasypt to have custom encryption in Springboot
[英]Creating a custom Jasypt PropertySource in Springboot
我正在使用Spring Boot创建一个访问数据库的简单Web应用程序。 我通过在application.properties
设置spring.datasource.*
属性来利用DataSource的自动配置功能。 这一切都很出色,非常快 - 很棒的工作人员@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
当使用mvn spring-boot:run
从maven运行时,这非常有效。 当我使用java -jar my-app.war
将其作为独立的战争运行时,会出现问题。 当我尝试连接到数据库时,应用程序仍然加载但失败,因为密码值仍然是加密的。 添加日志记录显示从未加载EncryptedPropertySourceLoader
。
对我来说这听起来像是一个类路径问题。 在maven下运行时,jar加载顺序是严格的,但是一旦在嵌入的tomcat下,没有什么可说的,我的自定义jar应该在Spring Boot之前加载。
我已经尝试将以下内容添加到我的pom.xml中以确保保留classpth但它似乎没有任何影响。
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<archive>
<manifest>
<mainClass>${start-class}</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
有没有人有任何想法? 提前致谢。
更新:
向前迈出的一步:我设法通过让EncryptedPropertySourceLoader
类实现org.springframework.core.PriorityOrdered
接口并从getOrder()
返回HIGHEST_PRECEDENCE
来解决这个问题。 这已经解决了未使用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运行时确实有效,我想我可以打折。 可能是包装问题......
这里有两个问题。
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;
}
}
从META-INF/spring.factories
加载org.springframework.boot.env.PropertySourceLoader
的org.springframework.core.io.support.SpringFactoriesLoader
类使用org.springframework.core.OrderComparator
对结果进行META-INF/spring.factories
。 这意味着应该首先返回此类,并且将负责为* .proerpties文件提供PropertySourceLoader实现。
2)第二个是可执行JAR / WAR的类加载问题,这似乎是由Windows上的Spring Boot 1.1.2.RELEASE版本中的错误引起的。 删除版本1.1.1.RELEASE或版本1.1.3.RELEASE解决了在maven外部运行时没有加载类和proerpties文件的各种问题。
你可以尝试一下: jasypt-spring-boot它基本上用环境包装加密版本中存在的所有PropertySource。 导入库后要做的两件事(如果使用maven则添加依赖关系)是使用@EnableEncryptableProperties注释@Configuration类,并通过属性配置加密算法和密码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.