我正在尝试为一个使用SSL的外部HTTP API创建FeignClient。
难题是-如何使用我的逻辑(在本例中为SSL Connection Factory)修改默认的Spring FeignClient。所以基本上我想保留Spring自动为FeignClient做的所有好事情,例如Hystrix,Sleuth跟踪等,并使其与我的SSL工厂一起使用。

将不胜感激任何建议。

这是我尝试做的事情:

我试图在ComponentScan之外提供自定义@Configuration:

@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通过注释使用它
    @FeignClient(name = "sslClient", configuration = CustomFeignConfiguration.class, url = "https://...")

this类似,实现了“TrustingSSLSocketFactory”。

现在,如果将客户端注入(inject)到Spring应用程序中,则可以看到调用了“feignBuilder”,并且成功加载了我的 key 。问题在于,创建的客户端实际上并未将指定的SSLFactory用于createSocket调用。所以我得到:
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),覆盖您在创建构建器时设置的客户端。

所以

@Bean
public Client feignClient()
{
    Client trustSSLSockets = new Client.Default(
            TrustingSSLSocketFactory.get("server1"),
            new NoopHostnameVerifier());

    log.info("feignClient called");
    return trustSSLSockets;
}

10-08 00:47