java - Jasypt 加密不适用于 Maven 配置文件

标签 java spring maven jasypt

我试图让 jasypt 解密一个(之前加密的)属性值,该值最终将用于登录数据库。解密工作正常,除非我引入 Maven 配置文件。我有一组 local/dev/prod 属性文件,它们是特定于环境的。

这是我的 spring3 配置的相关部分。这是代码示例中最关键的部分:这决定了如何设置解密以及将解密后的字符串设置为示例虚拟 bean。

  <bean id="jvmVariablesConfiguration" class="org.jasypt.encryption.pbe.config.EnvironmentPBEConfig"
         p:password="secret_password_here"/>

  <bean id="jvmConfigurationEncryptor" class="org.jasypt.encryption.pbe.StandardPBEStringEncryptor"
        p:config-ref="jvmVariablesConfiguration"/>

  <bean id="jvmPropertyConfigurer" class="org.jasypt.spring3.properties.EncryptablePropertyPlaceholderConfigurer"
        p:locations-ref="passwordProps">
    <constructor-arg ref="jvmConfigurationEncryptor"/>
  </bean>

  <util:list id="passwordProps">
    <value>classpath:database.properties</value>    
  </util:list>

  <encryption:encryptable-properties id="dbProps" encryptor="jvmConfigurationEncryptor" location="classpath:database.properties"/>

  <bean id="dummy" class="DummyPropertyTest">
    <property name="prop" value="${database.bar}"/>
  </bean>

在我的一个 Maven pom 中,我在此处指定配置文件。

  ...

  <profiles>
    <profile>
      <id>local</id>
      <properties>
        <build.profile.id>local</build.profile.id>
      </properties>
      <build>
        <filters>
          <filter>src/main/resources/properties/${build.profile.id}/database.properties</filter>
        </filters>
        <resources>
          <resource>
            <filtering>true</filtering>
            <directory>src/main/resources</directory>
            <includes>
              <include>**/*.properties</include>
              <include>**/*.xml</include>
            </includes>
          </resource>
        </resources>
      </build>
    </profile>

    <!--dev and prod profiles follow this in a similar pattern -->

....

我使用的是 jasypt 版本 1.9.1:

<dependency>
  <groupId>org.jasypt</groupId>
  <artifactId>jasypt-spring3</artifactId>
  <version>1.9.1</version>
</dependency>

我在/src/main/resources 中有一个主数据库属性文件 (database.properties) 设置,它具有以下占位符属性:

database.url=${database.url}
database.username=${database.username}
database.password=${database.password}
database.dialect=${database.dialect}
database.driver=${database.driver}
database.show_sql=${database.show_sql}
database.bar=${database.bar}

然后这是我的本地属性文件,位于/src/main/resources/properties/local/database.properties :

database.url=jdbc:hsqldb:hsql://localhost/db
database.username=sa
database.password=
database.dialect=MyHSQLDialect
database.driver=org.hsqldb.jdbcDriver
database.show_sql=true
database.bar=ENC(RSuprdBgcpdheiWX0hJ45Q==)

这是我的示例 spring bean 代码,只需读取为其设置的属性即可。如果一切正常,该值将被解密打印到标准输出。

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DummyPropertyTest {

    private String prop;

    public String getProp() {
        return prop;
    }

    public void setProp(String prop) {
        this.prop = prop;
    }

    @Value("#{dbProps['database.bar']}")
    public String otherProp;

    public String getOtherProp() {
        return otherProp;
    }

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("/META-INF/spring/applicationContext-common.xml");
        DummyPropertyTest dpt = (DummyPropertyTest) ctx.getBean("dummy");

        System.out.println("what's my property being set??: "+dpt.getProp());
        System.out.println("otherProp:"+dpt.getOtherProp());
    }
}

如果我调整 spring 配置以读取驻留在主属性文件上的属性,该文件通常只包含每个属性环境覆盖的占位符,则解密有效。但是尝试从本地属性文件读取加密属性时解密不起作用。我花了很多时间尝试调整 spring 配置,希望这可能只是一个类路径问题,但这似乎也没有帮助。

如果只是为了我需要加密的属性,我是否需要重写 Spring 如何看待属性前缀和后缀? (如果我这样做,这似乎适用于所有属性,而不仅仅是可加密的属性,因为 Jasypt 的 EncryptablePropertyPlaceholderConfigurer 是 Spring 的 PropertyPlaceholderConfigurer 的直接替代品)。

如果我按照图示设置了两个属性文件,那么这是程序的输出: what's my property being set??: ENC(RSuprdBgcpdheiWX0hJ45Q==)

如果我的主属性文件包含加密属性,则以下是程序的输出: what's my property being set??: sa

我不确定问题是出在 Spring 还是 Jayspt。我不认为这是马文。如果可能的话,我宁愿不放弃现在的 Maven 配置文件。

为了清晰起见,对运行时示例进行了编辑。

*更新*:如果我使用Jasypt Spring配置方式,我可以验证该值是否被正确解密 <encryption:encryptable-properties id="dbProps" encryptor="jvmConfigurationEncryptor" location="classpath:database.properties"/>

然后在我的测试 Bean 中,我可以连接一个成员以将属性分配给它:

    @Value("#{dbProps['database.bar']}")
    public String otherProp;

这似乎有效。但我确实需要 PropertyOverride 来工作,这样我才能正确地完成数据库配置。

最佳答案

我在同事的帮助下找到了解决方案。问题确实是 Maven 对配置文件的过滤。这是更正后的配置文件设置。之后,解密如梦如幻。因此,不需要将 @Value 注释直接单独连接到 bean 中:直接从 Spring 配置设置属性效果很好。

<profile>
  <id>local</id>
  <properties>
    <build.profile.id>local</build.profile.id>
  </properties>
  <build>
    <filters>
      <filter>src/main/resources/properties/${build.profile.id}/database.properties</filter>
      <filter>src/main/resources/properties/${build.profile.id}/cli.properties</filter>
    </filters>
    <resources>
      <resource>
        <filtering>true</filtering>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.properties</include>
        </includes>
        <excludes>
          <exclude>**/*.xml</exclude>
          <exclude>**/local/*.properties</exclude>
          <exclude>**/dev/*.properties</exclude>
          <exclude>**/prod/*.properties</exclude>
        </excludes>
      </resource>
      <resource>
        <filtering>false</filtering>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>
  </build>
</profile>

关于java - Jasypt 加密不适用于 Maven 配置文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19261124/

相关文章:

java - 在eclipse中调试时实时更改变量?

java - Hibernate 4 默认事务超时值

java - 通过包含另一个属性文件来扩展属性文件。 maven

maven - 编译 nativetoascii maven 插件

java - 将文件上传到保管箱(通过同步)

java - 为 iText 生成的 PDF 编写 JUnit

spring - Spring JMS/AQ。如何为多个使用者队列创建持久订阅。 ils子

java - Drools 规则在 Spring Boot Controller 中不起作用,但在 Junit Test 中起作用

java - Maven:如何使用包含外部库的可运行 jar(uber jar)

java - 程序中传递消息的数据结构?