我正在创建一个基于Spring WebFlux的Java客户端,它应该向外部端点发送请求,通过证书进行认证。我使用Spring的WebServiceTemplate做了类似的事情,在application.yaml文件中指定证书,如下所示:
client:
ssl:
enabled: true
key-store: /myapp/certificate/keystore.p12
key-store-password: SUPERSECRET
字符串
然后通过为HttpClient定义SSLContext,以便生成用于正确调用的相关bean。下面是上下文配置的摘录:
private SSLContext sslContext()
throws IOException, CertificateException, NoSuchAlgorithmException, KeyStoreException,
KeyManagementException, UnrecoverableKeyException {
return SSLContextBuilder.create()
.loadKeyMaterial(new File(keystore), keystorePassword.toCharArray(),
keystorePassword.toCharArray()).build();
}
型
事实证明,我不能通过使用WebClient(来自WebFlux)执行完全相同的事情。我所做的,按照各种SO响应和指南,如下所示:
通过加载相同的keystore.p12
来创建正确的SSLContext(我故意从下面的代码中删除了try-catch以增加可读性):
private WebClient getMtlsWebClient() {
HttpClient httpClient = HttpClient.create();
httpClient.secure(spec -> {
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(ResourceUtils.getFile(keyStorePath)), keyStorePass.toCharArray());
// Set up key manager factory to use key-store
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keyStore, keyStorePass.toCharArray());
spec.sslContext(SslContextBuilder.forClient()
.keyManager(keyManagerFactory)
.build());
});
return WebClient
.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();
}
型
然后简单地像下面这样触发调用:
return getMtlsWebClient()
.post()
.uri(externalServiceUrl)
.contentType(MediaType.TEXT_XML)
.accept(MediaType.TEXT_XML)
.acceptCharset(StandardCharsets.UTF_8)
.body(Mono.just(request), reqClazz)
.retrieve()
.bodyToMono(resClazz)
.retryWhen(
Retry
.fixedDelay(3, Duration.ofSeconds(1))
.filter(this::isAnyError)
).
map(res -> {
log.trace("Response payload: {}", res);
return res;
})
.onErrorMap(res -> {
log.error("Error response payload: {}", res);
return res;
});
型
不幸的是,我得到的响应是403禁止,实际上握手日志显示以下消息:
*** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00 ....
Warning: no suitable certificate found - continuing without client authentication
*** Certificate chain
<Empty>
***
型
虽然前面的WebServiceTemplate可以正常工作(我省略了证书链):
*** ServerHelloDone
[read] MD5 and SHA1 hashes: len = 4
0000: 0E 00 00 00 ....
matching alias: myalias
*** Certificate chain
型
谁能告诉我在上下文配置中缺少什么?
提前感谢您的帮助!
请让我知道如果你需要更多的信息…
1条答案
按热度按时间zbdgwd5y1#
我知道这是2岁,但这帮助了我:
字符串
来源:https://gist.github.com/hsg/6152944726e46ababcf47398398b4140