Java 为spring webflux WebClient配置带有reactor netty的HostnameVerifier
我正在尝试使用ssl和客户端主机名验证来配置SpringWebFlux WebClient(将reactor-netty隐藏起来)。我提供了javax.net.ssl.SSLContext、主机名验证器和可信主机名列表(作为字符串列表) 到目前为止,我已经用SSLContext配置了WebClient,但找不到配置主机名验证的方法 说明我的问题:我有一组受信任的服务主机名(字符串列表)和一个主机名验证器。我想用它配置我的WebClient 是否有可能使用javax.net.ssl.HostnameVerifier执行此操作?在反应堆netty中是否有其他方法 到目前为止,我得到的是:Java 为spring webflux WebClient配置带有reactor netty的HostnameVerifier,java,ssl,https,spring-webflux,reactor-netty,Java,Ssl,Https,Spring Webflux,Reactor Netty,我正在尝试使用ssl和客户端主机名验证来配置SpringWebFlux WebClient(将reactor-netty隐藏起来)。我提供了javax.net.ssl.SSLContext、主机名验证器和可信主机名列表(作为字符串列表) 到目前为止,我已经用SSLContext配置了WebClient,但找不到配置主机名验证的方法 说明我的问题:我有一组受信任的服务主机名(字符串列表)和一个主机名验证器。我想用它配置我的WebClient 是否有可能使用javax.net.ssl.Hostnam
WebClient.builder()
.clientConnector(
new ReactorClientHttpConnector(
opt -> opt.sslContext(new JdkSslContext(mySSLContext,
true, ClientAuth.OPTIONAL))))
.build();
您应该提供有效的证书颁发机构证书(
trustManager()
)和可选的用户证书,以及用于授权的私钥和私钥密码(keyManager()
)。
您的服务SSL证书应由您在trustManager()中定义的同一CA签名
正在使用服务主机名自动验证主机名。如果没有匹配的java.security.cert.CertificateException:将不会抛出任何主题替代名称。实际上,我找不到一种省略主机名验证的方法(不使用.trustManager(unsecuretrustmanagerfactory.INSTANCE)
省略整个SSL证书验证)
我已经在本地测试了这个解决方案。我的Web服务正在本地计算机上运行,但其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();
我用Netty HttpClient尝试了以下解决方案,效果也不错(使用自定义主机名匹配器禁用主机名验证)
公共HttpClient getHttpClient(HttpClientProperties){
//配置池资源
HttpClientProperties.Pool-Pool=properties.getPool();
连接提供者连接提供者;
if(pool.getType()==已禁用){
connectionProvider=connectionProvider.newConnection();
}
else if(pool.getType()=已修复){
connectionProvider=connectionProvider.fixed(pool.getName(),
pool.getMaxConnections(),pool.getAcquireTimeout());
}
否则{
connectionProvider=connectionProvider.elastic(pool.getName());
}
HttpClient HttpClient=HttpClient.create(connectionProvider)
.TCP配置(TCP客户端->{
if(properties.getConnectTimeout()!=null){
tcpClient=tcpClient.option(
ChannelOption.CONNECT\u超时\u毫秒,
getConnectTimeout());
}
//如果设置了代理主机,则配置代理。
HttpClientProperties.Proxy Proxy=properties.getProxy();
if(StringUtils.hasText(proxy.getHost())){
tcpClient=tcpClient.proxy(proxySpec->{
ProxyProvider.Builder=proxySpec
.type(ProxyProvider.Proxy.HTTP)
.host(proxy.getHost());
PropertyMapper映射=PropertyMapper.get();
从(proxy::getPort).whenNonNull()映射到(builder::port);
from(proxy::getUsername).whenHasText()时
.to(生成器::用户名);
map.from(proxy::getPassword).whenHasText()
.to(密码->生成器密码->密码);
from(proxy::getNonProxyHostsPattern).whenHasText()时
.至(建造商:非ProxyHosts);
});
}
返回tcpClient;
});
HttpClientProperties.Ssl Ssl=properties.getSsl();
如果(ssl.getTrustedX509CertificatesForTrustManager()。长度>0
||ssl.isUseSecureTrustManager()){
httpClient=httpClient.secure(sslContextSpec->{
//配置ssl
SslContextBuilder SslContextBuilder=SslContextBuilder.forClient();
X509Certificate[]受信任的X509Certificates=ssl
.getTrustedX509CertificatesForTrustManager();
如果(trustedX509Certificates.length>0){
sslContextBuilder.trustManager(TrustedX509证书);
}
else if(ssl.isuseesecuretrustmanager()){
sslContextBuilder
.trustManager(不安全的TrustManagerFactory.INSTANCE);
}
sslContextSpec.sslContext(sslContextBuilder)
.defaultConfiguration(ssl.getDefaultConfigurationType())
.handshakeTimeout(ssl.getHandshakeTimeout())
.closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout())
.closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout())
.handlerConfigurator(
(处理人)->{
SSLEngine引擎=handler.engine();
//engine.setNeedClientAuth(真);
SSLParameters params=新的SSLParameters();
列表匹配器=新的LinkedList();
锡
public HttpClient getHttpClient(HttpClientProperties properties){
// configure pool resources
HttpClientProperties.Pool pool = properties.getPool();
ConnectionProvider connectionProvider;
if (pool.getType() == DISABLED) {
connectionProvider = ConnectionProvider.newConnection();
}
else if (pool.getType() == FIXED) {
connectionProvider = ConnectionProvider.fixed(pool.getName(),
pool.getMaxConnections(), pool.getAcquireTimeout());
}
else {
connectionProvider = ConnectionProvider.elastic(pool.getName());
}
HttpClient httpClient = HttpClient.create(connectionProvider)
.tcpConfiguration(tcpClient -> {
if (properties.getConnectTimeout() != null) {
tcpClient = tcpClient.option(
ChannelOption.CONNECT_TIMEOUT_MILLIS,
properties.getConnectTimeout());
}
// configure proxy if proxy host is set.
HttpClientProperties.Proxy proxy = properties.getProxy();
if (StringUtils.hasText(proxy.getHost())) {
tcpClient = tcpClient.proxy(proxySpec -> {
ProxyProvider.Builder builder = proxySpec
.type(ProxyProvider.Proxy.HTTP)
.host(proxy.getHost());
PropertyMapper map = PropertyMapper.get();
map.from(proxy::getPort).whenNonNull().to(builder::port);
map.from(proxy::getUsername).whenHasText()
.to(builder::username);
map.from(proxy::getPassword).whenHasText()
.to(password -> builder.password(s -> password));
map.from(proxy::getNonProxyHostsPattern).whenHasText()
.to(builder::nonProxyHosts);
});
}
return tcpClient;
});
HttpClientProperties.Ssl ssl = properties.getSsl();
if (ssl.getTrustedX509CertificatesForTrustManager().length > 0
|| ssl.isUseInsecureTrustManager()) {
httpClient = httpClient.secure(sslContextSpec -> {
// configure ssl
SslContextBuilder sslContextBuilder = SslContextBuilder.forClient();
X509Certificate[] trustedX509Certificates = ssl
.getTrustedX509CertificatesForTrustManager();
if (trustedX509Certificates.length > 0) {
sslContextBuilder.trustManager(trustedX509Certificates);
}
else if (ssl.isUseInsecureTrustManager()) {
sslContextBuilder
.trustManager(InsecureTrustManagerFactory.INSTANCE);
}
sslContextSpec.sslContext(sslContextBuilder)
.defaultConfiguration(ssl.getDefaultConfigurationType())
.handshakeTimeout(ssl.getHandshakeTimeout())
.closeNotifyFlushTimeout(ssl.getCloseNotifyFlushTimeout())
.closeNotifyReadTimeout(ssl.getCloseNotifyReadTimeout())
.handlerConfigurator(
(handler)->{
SSLEngine engine = handler.engine();
//engine.setNeedClientAuth(true);
SSLParameters params = new SSLParameters();
List<SNIMatcher> matchers = new LinkedList<>();
SNIMatcher matcher = new SNIMatcher(0) {
@Override
public boolean matches(SNIServerName serverName) {
return true;
}
};
matchers.add(matcher);
params.setSNIMatchers(matchers);
engine.setSSLParameters(params);
}
)
;
});
}
return httpClient;
}