java - WebFlux WebClient 不发送证书
问题描述
我正在创建一个基于 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 响应和指南,我所做的如下:
通过加载相同的内容来创建正确的 SSLContext keystore.p12
(我有意从以下代码中删除了 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 FORBIDDEN,而且握手日志确实显示以下消息:
*** 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
谁能建议我在上下文配置中缺少什么?
预先感谢您的帮助!
如果您需要更多信息,请告诉我...
解决方案
推荐阅读
- html - 如何制作文本框以填补 html 中其他两个控件之间的空白
- c++ - 在 C++ 中打破两个循环
- mysql - 脚本mysql表导出| 它每次只导出 1 个表
- ontology - protege5.0中定义类之间的关系
- javascript - JavaScript中的AJAX文件上传进度条
- python - 在多线程中使用Python逐行读取文件是只读取第一行
- javascript - 如何在Node js中获取回调函数值
- ruby - 如何为包含包含“gets.chomp”的变量的 Ruby 方法编写 Rspec 测试?
- bootstrap-4 - Bootstrap 4 个垂直堆叠的按钮,每个按钮都有两列左对齐文本
- c# - 将 DateTime 转换为可为空的 long 时出错