Feign客户端发送HTTPS请求绕过认证

一、背景

一个Spring Boot项目,为了使用Harbor仓库,起初通过Spring RestTemplate完成了对Harbor仓库的HTTPS请求,后想改为使用Feign客户端的方式请求Harbor仓库。

二、配置过程

1、pom文件依赖添加
        
            org.springframework.cloud
            spring-cloud-starter-openfeign
            2.2.1.RELEASE
        
        
            io.github.openfeign
            feign-jackson
            9.3.1
        

其中openfeign是必须的依赖,而feign-jackson依赖主要是为了配置Feign客户端的编码和解码以支持JSON字符串

2、创建Feign客户端

import feign.Headers;
import feign.Param;
import feign.RequestLine;
import org.springframework.cloud.openfeign.FeignClient;

@FeignClient(name="feignClient")
public interface FeignClient {

    @Headers({"Content-Type: application/json", "Authorization: {token}"})
    @RequestLine("GET /api/users?username={username}")
    List> getUsers(URI baseUri,
                                       @Param("token") String token,
                                       @Param("username") String username);
}
3、在Service中调用Feign客户端完成对Harbor仓库的请求
import feign.Feign;
import feign.Target;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;

@Import(FeignClientsConfiguration.class)
@Service(value = "service")
public class ServiceImpl implements IService {
      private FeignClient feignClient;
      public ServiceImpl () {
            harborFeignClientV0 = Feign.builder().encoder(new JacksonEncoder())
                    .decoder(new JacksonDecoder()).target(Target.EmptyTarget.create(HarborFeignClientV0.class));
      }

     @Override
    public List> getUsers(DTO dTO){
        String usersUrl = getBaseUrl(dTO);
        try {
            SslUtils.ignoreSsl();
            return harborFeignClientV0.getUsers(new URI(usersUrl), dTO.getToken(), dTO.getUsername());
        } catch (Exception e){
            log.error("调用Harbor API错误:", e.getMessage());
            throw new RuntimeException(e);
        }
    }
}

相比较于Feign客户端发送HTTP请求,这里只多了一行代码SslUtils.ignoreSsl();,通过这个工具类,所有的HTTPS请求将会绕过证书检查。

4、工具类SslUtils

参考:https://blog.csdn.net/qq_34836433/article/details/78539009

public class SslUtils {
    private static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[1];
        TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }

    static class miTM implements TrustManager,X509TrustManager {
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(X509Certificate[] certs) {
            return true;
        }

        public void checkServerTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }

        public void checkClientTrusted(X509Certificate[] certs, String authType)
                throws CertificateException {
            return;
        }
    }

    /**
     * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
     * @throws Exception
     */
    public static void ignoreSsl() throws Exception{
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

三、踩坑过程

1、绕开HTTPS认证的另一个方法

参考:https://blog.csdn.net/Chipslyc/article/details/98851831
通过自己配置Feign客户端的配置绕开HTTPS认证检查,添加依赖和Feign客户端配置之后行不通,首先在添加依赖的时候,导致了好几次项目跑不起来;其次都配置好之后发送HTTPS请求时还是报错PKIX path building failed

2、依赖依赖之后单元测试无法正常启动

参考:http://www.lzhpo.com/article/93

启动单元测试报错Command line is too long

你可能感兴趣的:(Feign客户端发送HTTPS请求绕过认证)