gpt4 book ai didi

java - 如何使用不同的 SSL 客户端身份验证证书创建 Apache HttpClient 池

转载 作者:行者123 更新时间:2023-11-30 05:31:12 24 4
gpt4 key购买 nike

我一直在翻阅 Apache 文档和其他示例,试图创建一个使用 Apache HttpClient 来调用各种 RESTful Web 服务的客户端。 (这些 Web 服务中的每一个都可能需要不同的客户端证书进行身份验证)。最初,我创建了一个初始化 HttpClient 的静态代码块(带有 SSLContext 信息和池连接管理器):

private static CloseableHttpClient _client;
static {
HttpClientBuilder clientBuilder = HttpClients.custom();
SSLContextBuilder sslContextBuilder = SSLContexts.custom();
sslContextBuilder.loadTrustMaterial(new TrustSelfSignedStrategy());
sslContextBuilder.loadKeyMaterial(new File("clientcert.p12"), password, password, (aliases, socket) -> aliases.keySet().iterator().next());

SSLContext sslContext = sslContextBuilder.build();
HostnameVerifier allowAllHosts = new NoopHostnameVerifier();
SSLConnectionSocketFactory connectionFactory = new SSLConnectionSocketFactory(sslContext, allowAllHosts);
clientBuilder.setSSLSocketFactory(connectionFactory);

RegistryBuilder<ConnectionSocketFactory> regBuilder = RegistryBuilder.<ConnectionSocketFactory>create();
regBuilder.register("https", connectionFactory);
regBuilder.register("http", new PlainConnectionSocketFactory());
Registry<ConnectionSocketFactory> socketFactoryRegistry = regBuilder.build();

PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
clientBuilder.setConnectionManager(connectionManager);
_client = clientBuilder.build();
}

此时,我可以使用客户端来执行请求,并且只要服务器配置为允许访问 clientcert.p12,客户端身份验证就可以正常工作。

我需要的是能够根据所需客户端证书的值动态更改每个请求的客户端证书。

是否可以在动态更改客户端证书的同时重用静态 HttpClient?另外,如果这是可能的,我仍然会看到使用池连接管理器的性能优势吗?

最佳答案

有一个未记录的 http.socket-factory-registry 执行上下文属性,可以用来覆盖连接管理器在构造时设置的连接套接字工厂。

CloseableHttpClient httpClient = HttpClientBuilder.create()
.setSSLContext(SSLContexts.createSystemDefault())
.build();

SSLContext customSSlContext = SSLContexts.custom()
.loadKeyMaterial(new File("my-keystore.jks"), "sectret".toCharArray(), "sectret".toCharArray())
.build();

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", new SSLConnectionSocketFactory(customSSlContext))
.build();

HttpClientContext clientContext = HttpClientContext.create();
clientContext.setAttribute("http.socket-factory-registry", socketFactoryRegistry);
try (CloseableHttpResponse response = httpClient.execute(new HttpGet("https://host/stuff"), clientContext)) {
System.out.println(response.getStatusLine());
EntityUtils.consume(response.getEntity());
}

使用相同的客户端实例/相同的连接池来执行具有不同用户身份/安全上下文的多个线程的请求时,请务必谨慎使用。

关于java - 如何使用不同的 SSL 客户端身份验证证书创建 Apache HttpClient 池,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57519442/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com