【问题标题】:Set truststore programmatically以编程方式设置信任库
【发布时间】:2019-06-19 04:40:22
【问题描述】:

我想为我的应用程序设置自定义信任库。我想使用 System.setProperty()。在 tomcat 中设置不是一个选项。

所有的配置似乎都很好,但它不起作用。 我使用带有外部 tomcat 的 Spring boot 2.0.6。

我尝试了不同的地方进行配置,比如在 Bean 的 Postconstruct 中,就在 SpringApplication.run 之前。这是我最近的代码:

 static {
    System.setProperty("javax.net.debug", "all");
    System.setProperty("javax.net.ssl.trustStore", "/opt/grtc8/profiles/appconf/insurance/https-trust.p12"); 
    System.setProperty("javax.net.ssl.trustStorePassword", "xys");
    System.setProperty("javax.net.ssl.trustStoreType", "PKCS12");
 }

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(InsuranceCalculatorApplication.class);
}

public static void main(String[] args){

    SpringApplication.run(InsuranceCalculatorApplication.class, args);
}

我有一个证书异常,它似乎没有读取文件,或者其他什么。

我使用的是 Tomcat 8.5。

【问题讨论】:

  • 您有什么“证书异常”?

标签: java spring spring-boot tomcat truststore


【解决方案1】:

在您的 Java 代码中设置系统属性是一种相当可疑的做法。问题在于,只有当您可以确保设置属性的代码(总是)在使用属性的代码之前运行时,它才会运行。

在这种情况下,初始化 SSL 提供程序时会使用这些属性。这很可能是由在执行静态块之前发生的一些静态初始化触发的。

有几种方法可以解决这个问题:

  1. 使用-D 选项从命令行设置属性。根据您的要求,您可以做一些“启动时间”的魔术来选择信任存储;例如使用包装脚本或自定义启动器应用程序。

  2. 在 Java 代码中为您的 JVM 加载默认信任库等,而不是依赖于属性。例如:Load java trust store at runtime - after jvm have been launched?

    让这种方法与 Tomcat 一起工作可能会很棘手……假设您想为 Tomcat 的服务器端执行此操作。

  3. 显然,如果您使用的是SpringBoot,则可以替换默认的Tomcat Connector;见Spring Boot - replace default embedded Tomcat connector。这可能会给你一个“进入”的途径。

但我认为务实的解决方案是第一个。更改规则:-)

【讨论】:

  • 谢谢!不允许使用来自外部源的 -D 选项。
  • 有没有可能spring boot server.ssl。属性设置也在这里工作?据我所知,它仅适用于嵌入式 tomcat。
  • 另一件事,我正在使用 oauth2 身份验证,并且在应用程序启动之前我需要此值,因为我必须通过 https 到达身份验证服务器的 token_key 端点。
  • 通过System.setProperty() 设置这些属性确实有效,因此它不会是初始化顺序问题。我有几十个或几百个测试用例和main() 程序可以做到这一点。