Spring Boot - 密码存储密码在代码中设置

时间:2017-07-07 11:39:05

标签: java spring tomcat spring-boot keystore

Spring Boot版本: 1.5.4.RELEASE

我目前在Spring Boot应用程序的代码中设置server.ssl.key-store-password时遇到问题。我们将密码存储在保险库中,之前我通过-D属性传递它。然而,这对我们来说不是一个理想的解决方案。

解决方案似乎简单,下面就是我所做的:

@Bean
public ServletContextInitializer initializer() {
    final String keyStorePassword;
    // ... Get Password
    return servletContext -> servletContext.setInitParameter("server.ssl.key-store-password", keyStorePassword);
}

根据Spring Boot Documentation,这应该没问题,因为ServletConfig在<{em> {<1}}之前加载

不幸的是,Tomcat拒绝以这种方式设置application.properties。从我所看到的,server.ssl.key-store-password构造了一个AbstractNestablePropertyAccessor对象,它被提供给Tomcat,并用于构造密钥库。这是在org.springframework.boot.context.embedded.Ssl期间完成的,这显然是在构建SpringApplication.run() bean之前完成的。

所以我似乎需要'刷新'上下文(从我理解的是破坏/重新创建它),或者找到另一种方法。我可以使用类似的东西设置属性:

ServletConfig

但这有其自身的问题。我想在我的application.yml中存储保险箱密码的'标签',但如果我这样做,那么在Spring启动之前我无法访问该标签(无需手动解析application.yml,这构成它有自己的多个配置文件的问题)。

还有其他人遇到过这个问题的解决方案吗?也许我的做法是错误的,并且有一种更简单的做事方式。

2 个答案:

答案 0 :(得分:4)

是的,想通了。是在错误的轨道上。我应该做的是以下几点:

@Component
public class KeystoreInit {

    private final Environment environment;

    @Autowired
    public KeystoreInit(Environment environment) {
        this.environment = environment;
    }

    @Bean
    public ServerProperties serverProperties() {
        final ServerProperties serverProperties = new ServerProperties();
        final Ssl ssl = new Ssl();
        final String keystorePassword = getKeystorePassword();
        ssl.setKeyPassword(keystorePassword);
        System.setProperty("server.ssl.key-store-password", keystorePassword);
        serverProperties.setSsl(ssl);
        return serverProperties;
    }

    private String getKeystorePassword() {
        // ...
    }

}

这里的想法是我们正在创建初始的ServerProperties bean。然后加载此bean而不是新的ServerProperties,因此我们已经设置了具有密钥库密码的Ssl。由于我们未在server.ssl.key-store-password中设置application.yml,因此不会覆盖此内容。

我们@Autowire Environment以便我们可以访问server.ssl.key-store-label属性(我之前创建过),使用它来加载我们实际的server.ssl.key-store-password属性,然后通过系统属性设置它,以便可以在应用程序的其他位置访问它。

答案 1 :(得分:1)

  • spring boot:2.3.1.RELEASE
  • 您需要在方法中添加 @Primary 否则它会启动错误。我应该做的是以下内容:
@Component
public class KeystoreInit {

    private final Environment environment;

    @Autowired
    public KeystoreInit(Environment environment) {
        this.environment = environment;
    }

    @Bean
    @Primary
    public ServerProperties serverProperties() {
        final ServerProperties serverProperties = new ServerProperties();
        final Ssl ssl = new Ssl();
        final String keystorePassword = getKeystorePassword();
        ssl.setKeyPassword(keystorePassword);
        System.setProperty("server.ssl.key-store-password", keystorePassword);
        serverProperties.setSsl(ssl);
        return serverProperties;
    }

    private String getKeystorePassword() {
        // ...
    }
}