我正在尝试配置带有ssl和客户端主机名验证的spring-webflux WebClient(带有reactor netty)。为我提供了javax.net.ssl.SSLContext、HostnameVerifier和一个受信任的主机名列表(作为字符串列表)。
到目前为止,我已经使用SSLContext配置了WebClient,但我找不到配置主机名验证的方法。
说明一下我的问题:我有一组受信任的服务主机名(字符串列表)和一个主机名化器(HostNameVerifier)。我想用它配置我的WebClient。
这是我目前得到的:
WebClient.builder()
.clientConnector(
new ReactorClientHttpConnector(
opt -> opt.sslContext(new JdkSslContext(mySSLContext,
true, ClientAuth.OPTIONAL))))
.build();
您应该提供有效的证书颁发机构证书(TrustManager()
),还可以提供带有私钥和用于授权的私钥密码的用户证书(KeyManager()
)。您的服务SSL证书应该由您在trustManager()中定义的同一个CA签名。
主机名将自动与服务主机名进行验证。如果不匹配java.security.cert.CertificateException:No subject alternative names present
将引发异常。实际上,我找不到省略主机名验证的方法(而不省略整个SSL证书验证,方法是使用.trustManager(InsecureTrustManagerFactory.Instance)
)。
我已经在本地测试了这个解决方案。我的webservice正在本地计算机上运行,但它的SSL证书只包含DNS名称,而不包含IP地址。因此,为了调试的目的,我在主机文件中添加了条目,并将我的服务IP映射到正确的DNS名称。
SslContext sslContext = SslContextBuilder
.forClient()
.trustManager(new FileInputStream(caPath))
.keyManager(
new FileInputStream(userCertPath),
new FileInputStream(userPrivateKeyPath),
userPrivateKeyPassword
)
.build();
HttpClient httpClient = HttpClient.create()
.secure(t -> t.sslContext(sslContext));
WebClient webClient = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(httpClient))
.build();