美文网首页
Feign客户端发送HTTPS请求绕过认证

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

作者: Teddy_b | 来源:发表于2020-01-22 14:40 被阅读0次

    一、背景

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

    二、配置过程

    1、pom文件依赖添加
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
                <version>2.2.1.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-jackson</artifactId>
                <version>9.3.1</version>
            </dependency>
    

    其中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<Map<String, Object>> 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<Map<String, Object>> 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请求绕过认证

          本文链接:https://www.haomeiwen.com/subject/wqnuzctx.html