忽略 SSL 验证 HttpClient/Rest API - Groovy

Ignore SSL Verification HttpClient / Rest API - Groovy

我正在尝试使用 Groovy 消耗 Rest API,这是我正在使用的代码:

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
    
        CloseableHttpClient client = HttpClients.createDefault();
        HttpResponse response = null;

        HttpPost request = new HttpPost("http://path_to_my_server/rest_api_path");
        String auth = "login:password";
        String encoding = auth.bytes.encodeBase64().toString()
        request.setHeader("Authorization", "Basic " + encoding);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addPart("postVar",  new StringBody("value",ContentType.MULTIPART_FORM_DATA));
        HttpEntity entity = builder.build();
        request.setEntity(entity);
        response = client.execute(request);

问题是每次我执行它时,它都会向我显示错误:

error javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

我做了一些研究并测试了一些代码,例如:

https://gist.github.com/barata0/63705c0bcdd1054af2405e90c06f6b71

https://github.com/jgritman/httpbuilder/wiki/SSL

How to use SSL with a self-signed certificate in groovy?

所有这些都不起作用,有什么帮助吗?

虽然我不推荐这个选项,但您应该不要忽略 ssl 验证。更好的方法是创建一个包含可信证书的 truststore.jks 并将其加载到您的 http 客户端。

但是,您尝试执行的操作是可能的。您可以做的类似于此处的回答:

我建议使用 X509ExtenderTrustManager 而不是 X509TrustManager,因为它在这些用例中的行为可能会有所不同。

你能试试下面的代码片段吗:

创建自定义 TrustManager

import javax.net.ssl.SSLEngine;
import javax.net.ssl.X509ExtendedTrustManager;
import java.net.Socket;
import java.security.cert.X509Certificate;

public final class UnsafeX509ExtendedTrustManager extends X509ExtendedTrustManager {

    private static final X509ExtendedTrustManager INSTANCE = new UnsafeX509ExtendedTrustManager();
    private static final X509Certificate[] EMPTY_CERTIFICATES = new X509Certificate[0];

    private UnsafeX509ExtendedTrustManager() {}

    public static X509ExtendedTrustManager getInstance() {
        return INSTANCE;
    }

    @Override
    public void checkClientTrusted(X509Certificate[] certificates, String authType) {}

    @Override
    public void checkClientTrusted(X509Certificate[] certificates, String authType, Socket socket) {}

    @Override
    public void checkClientTrusted(X509Certificate[] certificates, String authType, SSLEngine sslEngine) {}

    @Override
    public void checkServerTrusted(X509Certificate[] certificates, String authType) {}

    @Override
    public void checkServerTrusted(X509Certificate[] certificates, String authType, Socket socket) {}

    @Override
    public void checkServerTrusted(X509Certificate[] certificates, String authType, SSLEngine sslEngine) {}

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        return EMPTY_CERTIFICATES;
    }

}

将其应用于您的 Http 客户端

HostnameVerifier hostnameVerifier = (host, sslSession) -> true;
TrustManager[] trustManagers = new TrustManager[]{UnsafeX509ExtendedTrustManager.getInstance()};

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustManagers, null);

LayeredConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
CloseableHttpClient httpClient = HttpClients.custom()
        .setSSLSocketFactory(socketFactory)
        .build();

在此处查看我对其他 Whosebug 的参考以获得更详细的解释: