feignclient https 接口调用报证书错误的解决方案

  • Post category:http

以下是关于“feignclient https 接口调用报证书错误的解决方案”的完整攻略:

问题描述

在使用FeignClient调用HTTPS接口时,可能会遇到证书错误的。本文将介绍如何解决这个问题。

解决步骤

以下是解决“FeignClient https 接口调用报证书错误”的步骤:

步骤一:了解问题

首先,需要了解这个问题的原因。这个问题通常是由于FeignClient默认使用的是JDK自带的证书库,而不是操作系统的证书库,导致无法验证服务器证书。

步骤二:解决问题

可以通过以下方法来解决这个问题:

方法1禁用证书验证

可以在FeignClient的配置中禁用证书验证,但这会降低安全性。

@Configuration
public class FeignConfig {

    @Bean
    public Client feignClient() {
        return new Client.Default(null, null) {
            @Override
            public Response execute(Request request, Request.Options options) throws IOException {
                SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(new TrustAllStrategy()).build();
                SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
                CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
                HttpUriRequest httpUriRequest = createHttpUriRequest(request, options);
                CloseableHttpResponse httpResponse = httpClient.execute(httpUriRequest);
                return toFeignResponse(httpResponse);
            }
        };
    }

    private HttpUriRequest createHttpUriRequest(Request request, Request.Options options) {
        RequestBuilder requestBuilder = RequestBuilder.create(request.method());
        requestBuilder.setUri(request.url());
        for (Map.Entry<String, Collection<String>> entry : request.headers().entrySet()) {
            String headerName = entry.getKey();
            for (String headerValue : entry.getValue()) {
                requestBuilder.addHeader(headerName, headerValue);
            }
        }
        return requestBuilder.build();
    }

    private Response toFeignResponse(CloseableHttpResponse httpResponse) throws IOException {
        int statusCode = httpResponse.getStatusLine().getStatusCode();
        Map<String, Collection<String>> headers = new HashMap<>();
        for (Header header : httpResponse.getAllHeaders()) {
            String headerName = header.getName();
            String headerValue = header.getValue();
            if (!headers.containsKey(headerName)) {
                headers.put(headerName, new ArrayList<>());
            }
            headers.get(headerName).add(headerValue);
        }
        Response.Builder builder = Response.builder();
        builder.status(statusCode);
        builder.headers(headers);
        HttpEntity entity = httpResponse.getEntity();
        if (entity != null) {
            builder.body(entity.getContent(), Charset.forName("UTF-8"));
        }
        return builder.build();
    }

    private static class TrustAllStrategy implements TrustStrategy {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return true;
        }
    }
}

在这个示例中,我们创建了一个自定义的FeignClient,禁用了证书验证。

方法2:使用操作系统的证书库

可以在FeignClient的配置中使用操作系统的证书库,这样就可以验证服务器证书。

@Configuration
public class FeignConfig {

    @Bean
    public Client feignClient() {
        SSLContext sslContext = SSLContexts.createSystemDefault();
        SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslConnectionSocketFactory).build();
        return new Client.Default(httpClient, null);
    }
}

在这个示例中,我们创建了一个自定义的FeignClient,使用了操作系统的证书库。

结论

本文介绍了解决“FeignClient https 接口调用报证书错误”的方法,包括禁用证书验证和操作系统的证书库。提供了两个示例,分别是禁用证书验证和使用操作系统的证书库。在实际应用中,需要根据体情况选择合适的方法来解决问题。