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

Ken*_*nco 9 java spring tomcat keystore spring-boot

Spring Boot 版本: 1.5.4.RELEASE

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

解决方案看起来很简单,下面是我所做的:

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

按照春季启动文档这应该是罚款,因为ServletConfig被加载之前application.properties

不幸的是,Tomcat 拒绝以server.ssl.key-store-password这种方式从集合开始。据我所知,它AbstractNestablePropertyAccessor构造了一个org.springframework.boot.context.embedded.Ssl对象,该对象提供给 Tomcat,并用于构造密钥库。这是在 期间完成的SpringApplication.run(),这显然是在构建ServletConfigbean之前完成的。

因此,似乎我需要“刷新”上下文(据我所知,它正在破坏/重新创建它),或者找到另一种方法。我可以使用以下内容设置属性:

public static void main(String[] args) {
    String keyStorePassword = getKeystorePassword();
    HashMap<String, Object> props = new HashMap<>();
    props.put("server.ssl.key-store-password", keyStorePassword);
    new SpringApplicationBuilder()
            .sources(TesterApplication.class)
            .properties(props)
            .run(args);
}
Run Code Online (Sandbox Code Playgroud)

不过这也有其自身的问题。我想在我的 application.yml 中存储保管库密码的“标签”,但如果我这样做,那么在 Spring 启动之前我无法访问该标签(无需手动解析 application.yml,这会造成多个配置文件本身的问题)。

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

Ken*_*nco 9

没错,想通了。走错了路。我应该做的是以下内容:

@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() {
        // ...
    }

}
Run Code Online (Sandbox Code Playgroud)

这里的想法是我们正在创建初始ServerPropertiesbean。然后加载这个 bean 而不是 fresh ServerProperties,所以我们Ssl的密钥库密码已经设置在那里了。这不会被覆盖,因为我们没有server.ssl.key-store-password在我们的application.yml.

我们@AutowireEnvironment这样我们就可以访问了server.ssl.key-store-label属性(我以前创建的),用它来装载我们的实际server.ssl.key-store-password属性,然后设置通过系统属性,以便它可以在程序的任何地方访问。