问题描述
我正在尝试为一个使用SSL的外部HTTP API创建FeignClient.难题是-如何使用我的逻辑(在本例中为SSL Connection Factory)修改默认的Spring FeignClient.因此,基本上,我想保留Spring自动为FeignClient做的所有好事情,例如Hystrix,Sleuth跟踪等,并使其与我的SSL工厂一起使用.
I'm trying to create a FeignClient for one external HTTP API which uses SSL.The struggle is - how to modify default Spring FeignClient with my logic, in this case SSL Connection Factory. So basically I wanna keep all the good things Spring automatically does for the FeignClients, like Hystrix, Sleuth tracing, etc and make it work with my SSL factory.
将感谢您的任何建议.
这是我想要做的:
我试图在ComponentScan之外提供自定义@Configuration:
I've tried to provide a custom @Configuration outside of ComponentScan:
@Configuration
public class CustomFeignConfiguration
{
@Bean
public Feign.Builder feignBuilder()
{
Client trustSSLSockets = new Client.Default(
TrustingSSLSocketFactory.get("server1"),
new NoopHostnameVerifier());
log.info("feignBuilder called");
return Feign.builder().client(trustSSLSockets);
}
...
}
让FeignClient通过注释使用
Made FeignClient use it through annotation
@FeignClient(name = "sslClient", configuration = CustomFeignConfiguration.class, url = "https://...")
在实现"TrustingSSLSocketFactory"的地方类似于此.
Where "TrustingSSLSocketFactory" is implemented similar to this.
现在,如果我将客户端注入Spring应用程序中,则可以看到调用了"feignBuilder",并且该加载器成功加载了我的密钥.问题在于,创建的客户端实际上并未将指定的SSLFactory用于createSocket调用.所以我得到:
Now if I inject my client in a Spring application, I can see that "feignBuilder" was called and it successfully loaded my keys. The problem is that the created client doesn't actually use the specified SSLFactory for createSocket calls. So I get:
Caused by: javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192) ~[na:1.8.0_72]
at sun.security.ssl.Alerts.getSSLException(Alerts.java:154) ~[na:1.8.0_72]
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:2023) ~[na:1.8.0_72]
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1125) ~[na:1.8.0_72]
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1375) ~[na:1.8.0_72]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1403) ~[na:1.8.0_72]
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1387) ~[na:1.8.0_72]
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:559) ~[na:1.8.0_72]
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185) ~[na:1.8.0_72]
at sun.net.www.protocol.http.HttpURLConnection.getInputStream0(HttpURLConnection.java:1513) ~[na:1.8.0_72]
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1441) ~[na:1.8.0_72]
at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:480) ~[na:1.8.0_72]
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:338) ~[na:1.8.0_72]
at feign.Client$Default.convertResponse(Client.java:152) ~[feign-core-9.3.1.jar:na]
推荐答案
创建Client
,因为它是自己的@Bean
,而不是构建器的一部分. builder.client(client)
稍后会被调用,覆盖您在创建构建器时设置的客户端.
Create the Client
as it's own @Bean
rather than part of the builder. builder.client(client)
gets called later on, overriding the client you set while creating the builder.
所以
@Bean
public Client feignClient()
{
Client trustSSLSockets = new Client.Default(
TrustingSSLSocketFactory.get("server1"),
new NoopHostnameVerifier());
log.info("feignClient called");
return trustSSLSockets;
}
这篇关于SpringBoot:具有SSL的FeignClient(p12)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!