erv*_*eeg 103

所有其他答案都已弃用或不适用于HttpClient 4.3.

这是一种在构建http客户端时允许所有主机名的方法.

CloseableHttpClient httpClient = HttpClients
    .custom()
    .setHostnameVerifier(AllowAllHostnameVerifier.INSTANCE)
    .build();
Run Code Online (Sandbox Code Playgroud)

或者,如果您使用的是4.4或更高版本,则更新的调用如下所示:

CloseableHttpClient httpClient = HttpClients
    .custom()
    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
    .build();
Run Code Online (Sandbox Code Playgroud)

  • 这适用于主机名不匹配(我假设),但是当证书未由受信任的机构签名时,它似乎不起作用. (12认同)

ZZ *_*der 82

您需要使用自己的TrustManager创建SSLContext,并使用此上下文创建HTTPS方案.这是代码,

SSLContext sslContext = SSLContext.getInstance("SSL");

// set up a TrustManager that trusts everything
sslContext.init(null, new TrustManager[] { new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                    System.out.println("getAcceptedIssuers =============");
                    return null;
            }

            public void checkClientTrusted(X509Certificate[] certs,
                            String authType) {
                    System.out.println("checkClientTrusted =============");
            }

            public void checkServerTrusted(X509Certificate[] certs,
                            String authType) {
                    System.out.println("checkServerTrusted =============");
            }
} }, new SecureRandom());

SSLSocketFactory sf = new SSLSocketFactory(sslContext);
Scheme httpsScheme = new Scheme("https", 443, sf);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(httpsScheme);

// apache HttpClient version >4.2 should use BasicClientConnectionManager
ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(cm);
Run Code Online (Sandbox Code Playgroud)

  • 嗯,它告诉我'新的SSLSocketFactory(ssslCont)'期待一个KeyStore,而不是一个SSLContext.我错过了什么吗? (18认同)
  • 我得到的错误是X509TrustManager无法转换为TrustManager. (2认同)
  • 确保您导入了正确的软件包,即从org.apache.http。 (2认同)
  • 任何人都知道如何使用`HttpClientBuilder`将所有这些放在一起? (2认同)

ok2*_*k2c 31

只是为了记录,有一个更简单的方法来实现与HttpClient 4.1相同

    SSLSocketFactory sslsf = new SSLSocketFactory(new TrustStrategy() {

        public boolean isTrusted(
                final X509Certificate[] chain, String authType) throws CertificateException {
            // Oh, I am easy...
            return true;
        }

    });
Run Code Online (Sandbox Code Playgroud)

  • 在HttpClient 4.3中不推荐使用SSLSocketFactory (8认同)
  • httpclient.getConnectionManager().getSchemeRegistry().register(new Scheme("https",443,sslsf)); (6认同)

Z4-*_*Z4- 31

只需要使用较新的HttpClient 4.5来做这件事,看起来他们已经弃用了4.4之后的一些东西,所以这里的代码片段适用于我并使用最新的API:

final SSLContext sslContext = new SSLContextBuilder()
        .loadTrustMaterial(null, (x509CertChain, authType) -> true)
        .build();

return HttpClientBuilder.create()
        .setSSLContext(sslContext)
        .setConnectionManager(
                new PoolingHttpClientConnectionManager(
                        RegistryBuilder.<ConnectionSocketFactory>create()
                                .register("http", PlainConnectionSocketFactory.INSTANCE)
                                .register("https", new SSLConnectionSocketFactory(sslContext,
                                        NoopHostnameVerifier.INSTANCE))
                                .build()
                ))
        .build();
Run Code Online (Sandbox Code Playgroud)


STM*_*STM 26

为了记录,使用httpclient 4.3.6测试并与流畅的api的Executor兼容:

CloseableHttpClient httpClient = HttpClients.custom().
                    setHostnameVerifier(new AllowAllHostnameVerifier()).
                    setSslcontext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy()
                    {
                        public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
                        {
                            return true;
                        }
                    }).build()).build();
Run Code Online (Sandbox Code Playgroud)

  • 对于HttpClient 4.4以上,您必须这样做 - 并且可能还需要使用`SSLContext`创建`SSLConnectionSocketFactory`,并在`Registry <ConnectionSocketFactory>`中定义它,如果您要创建`PoolingHttpClientConnectionManager `.其他答案更受欢迎,但不适用于HttpClient 4.4. (3认同)

Tho*_*s W 18

对于Apache HttpClient 4.4:

HttpClientBuilder b = HttpClientBuilder.create();

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() {
    public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {
        return true;
    }
}).build();
b.setSslcontext( sslContext);

// or SSLConnectionSocketFactory.getDefaultHostnameVerifier(), if you don't want to weaken
HostnameVerifier hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;

SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
        .register("http", PlainConnectionSocketFactory.getSocketFactory())
        .register("https", sslSocketFactory)
        .build();

// allows multi-threaded use
PoolingHttpClientConnectionManager connMgr = new PoolingHttpClientConnectionManager( socketFactoryRegistry);
b.setConnectionManager( connMgr);

HttpClient client = b.build();
Run Code Online (Sandbox Code Playgroud)

这是从我们的实际工作实施中提取的.

其他答案很受欢迎,但对于HttpClient 4.4,它们不起作用.我花了几个小时尝试和耗尽可能性,但似乎已经有非常重要的API更改和重新定位4.4.

另请参阅以下网址上的更全面的解释:http://literatejava.com/networks/ignore-ssl-certificate-errors-apache-httpclient-4-4/

希望有所帮助!

  • 我是我需要的SSLContext位.非常有必要. (2认同)

Mik*_*kov 18

Apache HttpClient 4.5.5

HttpClient httpClient = HttpClients
            .custom()
            .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
            .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
            .build();
Run Code Online (Sandbox Code Playgroud)

没有使用过弃用的API.

简单可验证的测试用例:

package org.apache.http.client.test;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;

public class ApacheHttpClientTest {

    private HttpClient httpClient;

    @Before
    public void initClient() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException {
        httpClient = HttpClients
                .custom()
                .setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, TrustAllStrategy.INSTANCE).build())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();
    }

    @Test
    public void apacheHttpClient455Test() throws IOException {
        executeRequestAndVerifyStatusIsOk("https://expired.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://wrong.host.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://self-signed.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://untrusted-root.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://revoked.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://pinning-test.badssl.com");
        executeRequestAndVerifyStatusIsOk("https://sha1-intermediate.badssl.com");
    }

    private void executeRequestAndVerifyStatusIsOk(String url) throws IOException {
        HttpUriRequest request = new HttpGet(url);

        HttpResponse response = httpClient.execute(request);
        int statusCode = response.getStatusLine().getStatusCode();

        assert statusCode == 200;
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @ggb667我找不到 `TrustAllStrategy.INSTANCE`,但我尝试自己实现它: `new SSLContextBuilder().loadTrustMaterial(null, (chain, authType) -&gt; true).build()` 并且它有效。 (3认同)
  • 谢谢你!只需在此答案中将“TrustAllStrategy.INSTANCE”更改为“TrustSelfSignedStrategy.INSTANCE”即可。 (2认同)

Dav*_*ker 13

如果您只想摆脱无效的主机名错误,您可以这样做:

HttpClient httpClient = new DefaultHttpClient();
SSLSocketFactory sf = (SSLSocketFactory)httpClient.getConnectionManager()
    .getSchemeRegistry().getScheme("https").getSocketFactory();
sf.setHostnameVerifier(new AllowAllHostnameVerifier());
Run Code Online (Sandbox Code Playgroud)

  • 自4.1起,不推荐使用sf.setHostnameVerifier方法.另一种方法是使用其中一个构造函数.例如:`SSLSocketFactory sf = new SSLSocketFactory(sslContext,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);` (8认同)

Ham*_* MP 9

我们正在使用HTTPClient 4.3.5,我们尝试了几乎所有解决方案都存在于stackoverflow上但没有任何问题,在思考并找出问题之后,我们来看下面的代码,它完美地工作,只需在创建HttpClient实例之前添加它.

在发布请求时调用的一些方法....

SSLContextBuilder builder = new SSLContextBuilder();
    builder.loadTrustMaterial(null, new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return true;
        }
    });

    SSLConnectionSocketFactory sslSF = new SSLConnectionSocketFactory(builder.build(),
            SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

    HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSF).build();
    HttpPost postRequest = new HttpPost(url);
Run Code Online (Sandbox Code Playgroud)

以正常形式继续您的请求


Tal*_*Kit 7

使用流畅的4.5.2我必须进行以下修改才能使其正常工作.

try {
    TrustManager[] trustAllCerts = new TrustManager[] {
       new X509TrustManager() {
    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }
    public void checkClientTrusted(X509Certificate[] certs, String authType) {  }

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

    SSLContext sc = SSLContext.getInstance("SSL");
    sc.init(null, trustAllCerts, new SecureRandom());
    CloseableHttpClient httpClient = HttpClients.custom().setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSslcontext(sc).build();

    String output = Executor.newInstance(httpClient).execute(Request.Get("https://127.0.0.1:3000/something")
                                      .connectTimeout(1000)
                                      .socketTimeout(1000)).returnContent().asString();
    } catch (Exception e) {
    }
Run Code Online (Sandbox Code Playgroud)


Swa*_*ath 6

这就是我做到的 -

  1. 创建我自己的MockSSLSocketFactory(下面附带的类)
  2. 用它来初始化DefaultHttpClient.如果使用代理,则需要提供代理设置.

初始化DefaultHTTPClient -

SchemeRegistry schemeRegistry = new SchemeRegistry();
    schemeRegistry.register(new Scheme("http", 80, PlainSocketFactory.getSocketFactory()));
    schemeRegistry.register(new Scheme("https", 443, new MockSSLSocketFactory()));
    ClientConnectionManager cm = new SingleClientConnManager(schemeRegistry);

    DefaultHttpClient httpclient = new DefaultHttpClient(cm);
Run Code Online (Sandbox Code Playgroud)

模拟SSL工厂 -

public class MockSSLSocketFactory extends SSLSocketFactory {

public MockSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException {
    super(trustStrategy, hostnameVerifier);
}

private static final X509HostnameVerifier hostnameVerifier = new X509HostnameVerifier() {
    @Override
    public void verify(String host, SSLSocket ssl) throws IOException {
        // Do nothing
    }

    @Override
    public void verify(String host, X509Certificate cert) throws SSLException {
        //Do nothing
    }

    @Override
    public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
        //Do nothing
    }

    @Override
    public boolean verify(String s, SSLSession sslSession) {
        return true; 
    }
};

private static final TrustStrategy trustStrategy = new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
        return true;
    }
};
}
Run Code Online (Sandbox Code Playgroud)

如果在代理后面,需要这样做 -

HttpParams params = new BasicHttpParams();
    params.setParameter(AuthPNames.PROXY_AUTH_PREF, getClientAuthPrefs());

DefaultHttpClient httpclient = new DefaultHttpClient(cm, params);

httpclient.getCredentialsProvider().setCredentials(
                        new AuthScope(proxyHost, proxyPort),
                        new UsernamePasswordCredentials(proxyUser, proxyPass));
Run Code Online (Sandbox Code Playgroud)


eld*_*dur 5

作为ZZ Coder 答案的扩展,覆盖主机名验证器会很好。

// ...
SSLSocketFactory sf = new SSLSocketFactory (sslContext);
sf.setHostnameVerifier(new X509HostnameVerifier() {
    public boolean verify(String hostname, SSLSession session) {
        return true;
    }

    public void verify(String host, String[] cns, String[] subjectAlts) throws SSLException {
    }

    public void verify(String host, X509Certificate cert) throws SSLException {
    }

    public void verify(String host, SSLSocket ssl) throws IOException {
    }
});
// ...
Run Code Online (Sandbox Code Playgroud)

  • 从 4.1 开始,sf.setHostnameVerifier 已被弃用。另一种方法是使用其中一个构造函数。例如:`SSLSocketFactory sf = new SSLSocketFactory(sslContext, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);` (7认同)

小智 5

使用 HttpClient 4.5.5 和 Fluent API 进行测试

final SSLContext sslContext = new SSLContextBuilder()
    .loadTrustMaterial(null, (x509CertChain, authType) -> true).build();

CloseableHttpClient httpClient = HttpClients.custom()
    .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
    .setSSLContext(sslContext).build();

String result = Executor.newInstance(httpClient)
    .execute(Request.Get("https://localhost:8080/someapi")
    .connectTimeout(1000).socketTimeout(1000))
    .returnContent().asString();
Run Code Online (Sandbox Code Playgroud)