是否可以构建一个使用 SSL/TLS JAVA_OPTS 作为其 SSLContext 的 Java 11 HttpClient?

Is it possible to build a Java 11 HttpClient that uses SSL/TLS JAVA_OPTS as its SSLContext?

我知道使用 Apache 的 HttpClientBuilder 你可以调用 useSystemProperties() 并且如果传递为JAVA_OPTS:

try (CloseableHttpClient client = HttpClientBuilder.create().useSystemProperties.build()) {
  // If javax.net.ssl props are set, make requests that require client auth
  // Otherwise make regular requests
}

我想对 Java 11 HttpClient 做一些类似的事情。这样做的原因是在我的用例中,我将密钥存储和信任存储视为可选,并且不必在我的代码中检查它们的存在会很好。基本上,如果它们存在,我想根据 JAVA_OPTS 设置一个 SSLContext;否则只需使用 "Default" context.

TLDR:您无需执行任何操作

新的 java.net.http.HttpClient,像旧的 HttpsURLConnection 和普通的 SSL[Server]Socket 和其他东西一样,默认为 SSLContext.getDefault() 默认使用系统属性 javax.net.ssl.{key,trust}Store* -- 只读一次,第一次在给定的 JVM 中被引用;之后所做的任何设置(必须通过代码)都将被忽略。

这些系统属性的初始值(就像其他输入到 JVM 的值一样,而不是像 java.version 那样自动设置)可以通过命令行上的 -D 选项设置 _JAVA_OPTIONS环境变量中;这两个也可以用于设置与 SSL/TLS 无关的其他系统属性和其他不是系统属性的选项。 Java 本身不使用 env var JAVA_OPTS,但是一些 运行 Java 作为从属的东西(比如服务监视器,IDE 、工具链等)可以使用该环境变量(的内容)作为创建的命令行的一部分。

请注意,如果您 指定 sysprops,则信任库默认为 JRE/lib/security/cacerts(通常随 'standard' public 一起提供Verisign/Symantec/Digicert、GoDaddy 等 CA,但密钥库没有默认值,即不进行客户端身份验证。