我正在尝试使用ssl和客户端主机名验证来配置spring-webflux WebClient(具有底层的Reactor Netty)。我提供了javax.net.ssl.SSLContext,HostnameVerifier和受信任的主机名列表(作为字符串列表)。
到目前为止,我已经使用SSLContext配置了WebClient,但是找不到配置主机名验证的方法。
陈述我的问题:我有一组信任的服务主机名(字符串列表)和一个HostnameVerifier。我想用它配置我的WebClient。
是否可以使用javax.net.ssl.HostnameVerifier做到这一点?反应堆网络中是否有替代方法?
到目前为止,这是我得到的:
WebClient.builder()
.clientConnector(
new ReactorClientHttpConnector(
opt -> opt.sslContext(new JdkSslContext(mySSLContext,
true, ClientAuth.OPTIONAL))))
.build();
Run Code Online (Sandbox Code Playgroud) 我需要查询证书/DNS 名称不匹配的第三方 API。证书中指定的主机名的最左侧标签事先未知(即CN=some-random-hash.example.com),因此我想使用自定义主机名验证器配置 HTTP 客户端。
当使用通过 获取的默认Reactor NettyHttpClient.create()客户端时,HostnameChecker类会失败证书验证并导致抛出异常:
java.security.cert.CertificateException: No subject alternative DNS name matching XXX found.
at sun.security.util.HostnameChecker.matchDNS(HostnameChecker.java:214)
at sun.security.util.HostnameChecker.match(HostnameChecker.java:96)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:455)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(X509TrustManagerImpl.java:436)
at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java:252)
at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:136)
at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1626)
... 30 more
Run Code Online (Sandbox Code Playgroud)
这个相关答案建议按如下方式实现 SNIMatcher:
HttpClient.create()
.secure(sslContextSpec -> sslContextSpec
.sslContext(sslContext)
.handlerConfigurator((handler) -> {
SSLEngine engine = handler.engine();
SSLParameters params = new SSLParameters();
List<SNIMatcher> matchers = new LinkedList<>();
SNIMatcher matcher = new SNIMatcher(0) {
@Override
public boolean matches(SNIServerName serverName) {
return true; …Run Code Online (Sandbox Code Playgroud)