我有一个带有自定义RestTemplate的Spring应用程序,它从文件(从资源文件夹)加载客户端证书。
现在我如何也可以从文件中向这个RestTemplate添加CA证书(PEM文件)?(或者用spring引导实现目标的其他方法?)
@Bean public RestTemplate restTemplate() ... {
SSLContext sslContext = new SSLContextBuilder()
.loadTrustMaterial(new URL(clientCert), str.toCharArray()).build();
SSLConnectionSocketFactory sslConFactory = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConFactory).build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(requestFactory);
}发布于 2022-08-10 22:02:16
不久前,我遇到了一些在用例中可能有帮助的代码。
它可以在这个储存库获得麻省理工学院的许可。
重要工件是在这个包裹中定义的。
基本上,库提出了一个名为SSLContextFactory的助手类。
这个类定义了一个方法,用于创建一个带有客户端证书的SSLContext、它的密码和相应的CA证书,最后一个证书是从一个名为makeContext的证书文件中复制的,为了方便起见:
public SSLContext makeContext(File clientCertFile, String clientCertPassword, String caCertString) throws Exception {
final KeyStore keyStore = loadPKCS12KeyStore(clientCertFile, clientCertPassword);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("X509");
kmf.init(keyStore, clientCertPassword.toCharArray());
KeyManager[] keyManagers = kmf.getKeyManagers();
final KeyStore trustStore = loadPEMTrustStore(caCertString);
TrustManager[] trustManagers = {new CustomTrustManager(trustStore)};
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
return sslContext;
}如您所见,它使用不同的帮助方法和助手类CustomTrustManager。
请注意,这个解决方案已经相当过时了,但我认为它仍然是合适的。
然后,在构造makeContext时使用RestTemplate方法
@Bean public RestTemplate restTemplate() {
SSLContextFactory sslContextFactory = SSLContextFactory.getInstance();
SSLContext sslContext = sslContextFactory.makeContext(clientCert, str.toCharArray(), caCertPem);
SSLConnectionSocketFactory sslConFactory = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConFactory).build();
ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient);
return new RestTemplate(requestFactory);
}如果您的PEM文件包含证书链,则可以通过以下内容修改在loadPEMTrustStore中定义的SSLContextFactory方法:
private KeyStore loadPEMTrustStore(String certificateString) throws Exception {
try (InputStream certificateStream = certificateString.getBytes()) {
CertificateFactory certificateFactory =
CertificateFactory.getInstance("X.509");
// note the change in the method, we use generateCertificates
Collection<X509Certificate> certificates =
(Collection<X509Certificate>)
certificateFactory.generateCertificates(certificateStream);
KeyStore trustStore =
KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null);
String alias;
for (X509Certificate certificate : certificates) {
alias = certificate.getSubjectX500Principal().getName();
trustStore.setCertificateEntry(alias, certificate);
}
return trustStore;
}
}https://stackoverflow.com/questions/73282644
复制相似问题