![](/img/trans.png)
[英]Spring Boot - client server REST API with self-signed certificate
[英]How to include client certificate when making REST API call to an external service - Spring Boot?
我试图通过在 Spring Boot 中包含 pfx 文件来调用外部 API 端点,但我得到:
Request processing failed; nested exception is org.springframewrk.web.client.ResourceAccessException: I/O error...
Connection reset; nested excrption is java.net.SocketExceptin: Connection reset
我也尝试将属性添加到 application.properties 中,但也没有工作。
我遵循的代码: 如何在 spring 引导休息模板中使用 .pfx 证书和密码调用安全休息 api? 哪个不起作用我也尝试了微小的更改,但也不起作用
它在包含 pfx 文件的邮递员中工作正常。
为 Http 客户端配置 ssl 可能很棘手,但是当您知道如何去做时,它就很简单了。 在您的情况下,您需要做的是将客户端证书作为KeyManager
加载到SSLContext
,并将受信任的服务器证书作为TrustManager
加载到SSLContext
。 我在您的评论中看到您正在使用 Apache 的 closableHttpClient。 Apache 有 4 个 http 客户端,我不清楚您使用的是哪一个,所以我在这里发布了所有四个示例:
SSL上下文
首先让我们创建 SSLContext,稍后我们将使用它来配置 http 客户端:
import javax.net.ssl.*;
import java.io.File;
import java.io.InputStream;
import java.security.KeyStore;
import java.util.Objects;
class SslExample {
public static void main(String[] args) throws Exception {
//Traditional flow of creating sslContext
String keyStorePath = "keystore.p12";
String trustStorePath = "truststore.p12";
char[] keyStorePassword = "secret".toCharArray();
char[] trustStorePassword = "secret".toCharArray();
KeyStore keyStore = KeyStore.getInstance("PKCS12");
KeyStore trustStore = KeyStore.getInstance("PKCS12");
try(InputStream keyStoreInputStream = SslExample.class.getClassLoader().getResourceAsStream(keyStorePath);
InputStream trustStoreInputStream = SslExample.class.getClassLoader().getResourceAsStream(trustStorePath)) {
Objects.requireNonNull(keyStoreInputStream);
Objects.requireNonNull(trustStoreInputStream);
keyStore.load(keyStoreInputStream, keyStorePassword);
trustStore.load(trustStoreInputStream, trustStorePassword);
}
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePassword);
KeyManager[] keyManagers = keyManagerFactory.getKeyManagers();
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init(trustStore);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagers, trustManagers, null);
//Alternative - Creating sslContext with Apache SSLContextBuilder
SSLContext sslContext1 = SSLContextBuilder.create()
.loadKeyMaterial(new File("keystore.p12"), "secret".toCharArray(), "secret".toCharArray())
.loadTrustMaterial(new File("truststore.p12"), "secret".toCharArray())
.build();
}
}
Apache 4 的 HttpClient
LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
CloseableHttpClient client = HttpClients.custom()
.setSSLSocketFactory(socketFactory)
.build();
Apache 4 的异步 HttpClient
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setSSLContext(sslContext)
.build();
client.start();
Apache 5 的 HttpClient
LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext);
HttpClientConnectionManager connectionManager = PoolingHttpClientConnectionManagerBuilder.create()
.setSSLSocketFactory(socketFactory)
.build();
CloseableHttpClient client = HttpClients.custom()
.setConnectionManager(connectionManager)
.build();
用于 Apache 5 的异步 HttpClient
AsyncClientConnectionManager connectionManager = PoolingAsyncClientConnectionManagerBuilder.create()
.setTlsStrategy(new BasicClientTlsStrategy(sslContext))
.build();
CloseableHttpAsyncClient client = HttpAsyncClients.custom()
.setConnectionManager(connectionManager)
.build();
client.start();
您可以重试上述配置并在此处分享您的结果吗?
您可以将客户端证书放在 SpringBoot 应用程序资源文件夹中,然后设置javax.net.ssl.keyStore
属性。 然后,一旦你想发出请求,你可以创建一个自定义的HttpClient
并设置SSLContext
如下:
public static void main(String[] args) throws Exception {
SpringApplication.run(DemoApplication.class, args);
System.setProperty("javax.net.ssl.keyStore", new ClassPathResource("example.p12").getFile().getAbsolutePath());
CloseableHttpClient httpClient = HttpClients.custom().setSSLContext(SSLContext.getDefault()).build();
httpClient.execute(
new HttpGet("https://prod.idrix.eu/secure/"));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.