背景
在用openfeign做接口对接时,如果接口是https时,就需要对ssl证书进行校验。由于近些年spring剥离了对ribbon的支持,全面支持loadbalancer。spring-cloud-loadbalancer和openfeign集成时,该如何处理https请求?
代码示例
编写ssl的处理器,我这里做的是跳过证书的处理,如果信任证书,可以根据自己的实际需求做相应的调整。
import feign.Client;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.cloud.openfeign.loadbalancer.FeignBlockingLoadBalancerClient;
import org.springframework.context.annotation.Bean;
import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class IgnoreSSLCheckConfiguration {
/**
@desc 初始化一个openfeign的client,需要注意的是一定要用loadbalancer提供的feignclient进行初始化,否则会在负载时找不到对应的地址。
**/
@Bean
public Client feignClient(LoadBalancerClient loadBalancerClient, LoadBalancerClientFactory loadBalancerClientFactory) {
return new FeignBlockingLoadBalancerClient(new Client.Default(getSSLSocketFactory(), new HostnameVerifier(){
@Override
public boolean verify(String s, SSLSession sslSession) {
return true;
}
}), loadBalancerClient, loadBalancerClientFactory);
}
/**
@desc 基于jdk获取SSLSocketFactory,当然也可以利用三方的包进行获取,例如apache-httpclient等。
**/
private SSLSocketFactory getSSLSocketFactory() {
SSLContext ctx = null;
try {
ctx = SSLContext.getInstance("SSL");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
ctx.init(null, new TrustManager[]{tm}, null);
} catch (Exception e) {
throw new RuntimeException(e);
}
return ctx.getSocketFactory();
}
}
openfeign接口上直接上面的处理配置类即可
/**
@desc @FeignClient注解属性configuration上指定上面的编写的IgnoreSSLCheckConfiguration处理类即可。
注意:IgnoreSSLCheckConfiguration千万不要加上@Configuration的注解,否则会变成一个全局的处理器。
**/
@FeignClient(name = "feign-attempt-client",configuration=IgnoreSSLCheckConfiguration.class)
@LoadBalancerClient(name = "feign-attempt-client")
public interface APPFeignClient {
/**
* 文印 用户名 密码登录
* @param loginReqDto
* @return
*/
@RequestMapping(method = RequestMethod.POST, value = "/auth/login?type=0")
public ResultData<UserToken> login(LoginReqDto loginReqDto);
}
总结
核心点就是创建一个loadbalancer支持的openfeign的客户端,通过源码分析找到FeignBlockingLoadBalancerClient类,分析构造方法后发现传入一个openfeign的client即可。