我有一个 Web 应用程序,我使用 X.509 公钥身份验证机制保护其其余端点的安全。为了详细解释它,我必须将示例客户端的公共证书添加到我的服务器 Web 应用程序的 java 信任存储中。当然,我的服务器也有一个包含服务器密钥对的 java 密钥库。因此,这里一切都很好,任何通过有效客户端证书的服务器调用都可以得到无缝身份验证。没有问题。
将来,我需要根据需要将新的客户端证书添加到同一服务器信任存储中。将新的客户端证书添加到服务器信任存储中是一个离线过程,可以通过 java keytool 等工具来处理。
但我不想重新启动服务器进程来刷新信任存储中的其他客户端证书。我希望每当任何新的客户端证书添加到信任存储区时,我的服务器进程都会自动重新加载其信任存储区。
我什至愿意通过某些 http 挂钩向我的服务器进程发送触发事件,以启动信任存储重新加载。但没有什么比自动重新加载更好的了。有什么指点吗?
只要您有办法为您的服务器配置提供 sslcontext 或 keymanager/trustmanager,这是可能的。由于此选项在 JDK 中不可用,因此我创建了一个 library 来启用此选项。另请参阅此处,了解与您类似的问题的详细答案:重新加载 java.net.http.HttpClient 的 SSLContext
在上面的链接中,OP 要求重新加载客户端 ssl 配置,但服务器也可以这样做。它还包含使用 tomcat/jetty、vertx、quarkus 等配置 spring 的链接
您可以像下面的代码片段一样配置它:
SSLFactory baseSslFactory = SSLFactory.builder()
.withDummyIdentityMaterial()
.withDummyTrustMaterial()
.withSwappableIdentityMaterial()
.withSwappableTrustMaterial()
.build();
Runnable sslUpdater = () -> {
SSLFactory updatedSslFactory = SSLFactory.builder()
.withIdentityMaterial(Paths.get("/path/to/your/identity.jks"), "password".toCharArray())
.withTrustMaterial(Paths.get("/path/to/your/truststore.jks"), "password".toCharArray())
.build();
SSLFactoryUtils.reload(baseSslFactory, updatedSslFactory)
};
// initial update of ssl material to replace the dummies
sslUpdater.run();
// update ssl material every hour
Executors.newSingleThreadScheduledExecutor().scheduleAtFixedRate(sslUpdater, 1, 1, TimeUnit.HOURS);
您可以在休息端点调用在触发器上更新的 ssl,将其安排在给定时间或您喜欢的任何其他类型的逻辑。