Ignoring SSL certificate in Apache HttpClient 4.3
Asked Answered
M

18

115

How to ignore SSL certificate (trust all) for Apache HttpClient 4.3?

All the answers that I have found on SO treat previous versions, and the API changed.

Related:

Edit:

  • It is only for test purposes. Kids, don't try it at home (or in production)
Maurilla answered 22/10, 2013 at 12:12 Comment(0)
S
157

The code below works for trusting self-signed certificates. You have to use the TrustSelfSignedStrategy when creating your client:

SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        builder.build());
CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
        sslsf).build();

HttpGet httpGet = new HttpGet("https://some-server");
CloseableHttpResponse response = httpclient.execute(httpGet);
try {
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
} finally {
    response.close();
}

I did not include the SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER on purpose: The point was to allow testing with self signed certificates so you don't have to acquire a proper certificate from a certification authority. You can easily create a self-signed certificate with the correct host name, so do that instead of adding the SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER flag.

Sieber answered 22/10, 2013 at 12:50 Comment(8)
I had to add the argument SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER to the constructor to get this working with the HttpClientBuilder (as mentioned in holmis83's response to vasekt).Hartshorn
also refer to the example on the httpclient site hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/…Mullins
I also had to use the ALLOW_ALL_HOSTNAME_VERIFIER: SSLConnectionSocketFactory(builder.build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);Apennines
This code works for me without using deprecated constructor with argument SSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIERSopher
I wish you had specified full reference of the class you were using. Multiple classes called SSLContextBuilder are found by Idea.Intercostal
The answer is pretty old, but I'm pretty sure I meant this one: hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/…. As you can see it's deprecated. Maybe later I will update the answer for the latest versionSieber
SSLContextBuilder is deprecated i guessFlacon
Does this still work? I'm unable to find some of these classnames anywhere I can import them.Flinty
M
100

If you are using PoolingHttpClientConnectionManager procedure above doesn't work, custom SSLContext is ignored. You have to pass socketFactoryRegistry in contructor when creating PoolingHttpClientConnectionManager.

SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        return true;
    }
});
SSLContext sslContext = builder.build();
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
        sslContext, new X509HostnameVerifier() {
            @Override
            public void verify(String host, SSLSocket ssl)
                    throws IOException {
            }

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

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

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

Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder
        .<ConnectionSocketFactory> create().register("https", sslsf)
        .build();

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(
        socketFactoryRegistry);
CloseableHttpClient httpclient = HttpClients.custom()
        .setConnectionManager(cm).build();
Megdal answered 13/11, 2013 at 10:11 Comment(6)
Instead of building your own X509HostnameVerifier, you can use SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER.Moneybags
As marked below by @rich95, the default for HttpClients is to give you a PoolingHttpClient, so this is relevant very often. I had to try quite a few of these answers before finding I needed this.Geoponics
Tried to apply this on WebSphere and got "java.security.KeyStoreException: IBMTrustManager: Problem accessing trust store java.io.IOException: Invalid keystore format " To avoid you need pass KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); instead of null to builder.loadTrustMaterialCasefy
Actually, with HttpClient 4.5, both HttpClients.custom().setConnectionManager(cm).build() and HttpClients.custom().setSSLSocketFactory(connectionFactory).build() will work, so you don't need to create a PoolingHttpClientConnectionManagerAntedate
How to use PoolingHttpClientConnectionManager after creating this , my code is working but i want to know does connection pooling works or notMycetozoan
The service I call had issued me whitelisted certificate to call and I was simply using System.setProperty(SSL_TRUSTSTORE_PASSWORD_KEY, "KeystorePassword"); to set certificates. Now after adding PoolingHttpClientConnectionManager, its not picking up right certs from system properties throwing handshake exceptions, will the above code still be helpful?Phrygian
G
43

As an addition to the answer of @mavroprovato, if you want to trust all certificates instead of just self-signed, you'd do (in the style of your code)

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

or (direct copy-paste from my own code):

import javax.net.ssl.SSLContext;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.ssl.SSLContexts;

// ...

        SSLContext sslContext = SSLContexts
                .custom()
                //FIXME to contain real trust store
                .loadTrustMaterial(new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] chain,
                        String authType) throws CertificateException {
                        return true;
                    }
                })
                .build();

And if you want to skip hostname verification as well, you need to set

    CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
            sslsf).setSSLHostnameVerifier( NoopHostnameVerifier.INSTANCE).build();

as well. (ALLOW_ALL_HOSTNAME_VERIFIER is deprecated).

Obligatory warning: you shouldn't really do this, accepting all certificates is a bad thing. However there are some rare use cases where you want to do this.

As a note to code previously given, you'll want to close response even if httpclient.execute() throws an exception

CloseableHttpResponse response = null;
try {
    response = httpclient.execute(httpGet);
    System.out.println(response.getStatusLine());
    HttpEntity entity = response.getEntity();
    EntityUtils.consume(entity);
}
finally {
    if (response != null) {
        response.close();
    }
}

Code above was tested using

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

And for the interested, here's my full test set:

import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import org.junit.Test;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLPeerUnverifiedException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class TrustAllCertificatesTest {
    final String expiredCertSite = "https://expired.badssl.com/";
    final String selfSignedCertSite = "https://self-signed.badssl.com/";
    final String wrongHostCertSite = "https://wrong.host.badssl.com/";

    static final TrustStrategy trustSelfSignedStrategy = new TrustSelfSignedStrategy();
    static final TrustStrategy trustAllStrategy = new TrustStrategy(){
        public boolean isTrusted(X509Certificate[] chain, String authType)
                throws CertificateException {
            return true;
        }
    };

    @Test
    public void testSelfSignedOnSelfSignedUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLHandshakeException.class)
    public void testExpiredOnSelfSignedUsingCode() throws Exception {
        doGet(expiredCertSite, trustSelfSignedStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnSelfSignedUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustSelfSignedStrategy);
    }

    @Test
    public void testSelfSignedOnTrustAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy);
    }
    @Test
    public void testExpiredOnTrustAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy);
    }
    @Test(expected = SSLPeerUnverifiedException.class)
    public void testWrongHostOnTrustAllUsingCode() throws Exception {
        doGet(wrongHostCertSite, trustAllStrategy);
    }

    @Test
    public void testSelfSignedOnAllowAllUsingCode() throws Exception {
        doGet(selfSignedCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testExpiredOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }
    @Test
    public void testWrongHostOnAllowAllUsingCode() throws Exception {
        doGet(expiredCertSite, trustAllStrategy, NoopHostnameVerifier.INSTANCE);
    }

    public void doGet(String url, TrustStrategy trustStrategy, HostnameVerifier hostnameVerifier) throws Exception {
        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).setSSLHostnameVerifier(hostnameVerifier).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
    public void doGet(String url, TrustStrategy trustStrategy) throws Exception {

        SSLContextBuilder builder = new SSLContextBuilder();
        builder.loadTrustMaterial(trustStrategy);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build());
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(
                sslsf).build();

        HttpGet httpGet = new HttpGet(url);
        CloseableHttpResponse response = httpclient.execute(httpGet);
        try {
            System.out.println(response.getStatusLine());
            HttpEntity entity = response.getEntity();
            EntityUtils.consume(entity);
        } finally {
            response.close();
        }
    }
}

(working test project in github)

Guanase answered 22/10, 2013 at 13:39 Comment(16)
HttpClient#execute will never return a null response object in case of an exception. Moreover, stock HttpClient implementations will ensure automatic deallocation of all system resources such as leased connections in case of an exception during request execution. Exception handling used by mavroprovato is perfectly adequate.Jinks
@oleg the point of Closable interface is to "Close[...] stream and release any system resources associated with it. If the stream is already closed then invoking this method has no effect." so it is best practice to use it even if it wouldn't be needed. Also, I don't understand the comment of returning null response - of course it doesn't, if it throws an exception, it doesn't return anything?Guanase
Apache HttpClient never ever returns a null or partially initialized response object. This has nothing to do with how many times #close gets invoked, but rather completely unnecessary null check in the finally clauseJinks
@oleg and never does the code I've given assume it would return a null or partially initialized response object, or even check such a case. I don't have a clue what you're talking about?Guanase
null check is for the case of throwing exceptions in the execute method, not for checking return values. If an execute method throws an exception, response variable will remain in the original state, null.Guanase
[sigh] which completely unnecessary given that HttpResponse can never be null and in case of an exception the #execute method will terminate without returning a response ;-)Jinks
@AllanRuin what isn't?Guanase
@Guanase the CloseableHttpClient I build with builder you mentioned did not bypass all certificates.Antin
@AllanRuin did you confirm is it about them not being trusted or something else?Guanase
@Guanase Yes, I'm sure it's cause by certificate. Though I solved my problem, here is my question #23242697Antin
@AllanRuin it's caused by the certificate, yes, but it doesn't seem it's caused by certificate not being trusted, but due to other issues. This code is about weather certificate is trusted or not. My understanding is that in your case it fails before it checks if the certificate is trusted or not. But you're correct that the subject of this thread is about ignoring the certificate and not about the reason.Guanase
The way to trust all certificates really saves my day, thank you!Antedate
The above didn't compile in 4.5.2 I had to insert, as first parameter in the call to loadTrustMaterial (KeyStore) null. Also, I did a: .setHostnameVerifier(SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER) when creating the ClosableHttpClientHeed
@MarcusJuniusBrutus just confirmed that code works on both 4.5.2 and 4.5.3, with or without the first null parameter.Guanase
@MarcusJuniusBrutus but you're correct on hostname verifier, it'll fail if hostname is wrong without that. I'll update on that part. ALLOW_ALL_HOSTNAME_VERIFIER is deprecated though, use NoopHostnameVerifier.INSTANCEGuanase
Great answer, thanks. To resolve SSLPeerUnverifiedException, I needed to change where/how the NoopHostnameVerifier was implemented: SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), NoopHostnameVerifier.INSTANCE); Don't know why but that worked for me (HttpClient 4.5.10).Ytterbia
B
24

One small addition to the answer by vasekt:

The provided solution with the SocketFactoryRegistry works when using PoolingHttpClientConnectionManager.

However, connections via plain http don't work any longer then. You have to add a PlainConnectionSocketFactory for the http protocol additionally to make them work again:

Registry<ConnectionSocketFactory> socketFactoryRegistry = 
  RegistryBuilder.<ConnectionSocketFactory> create()
  .register("https", sslsf)
  .register("http", new PlainConnectionSocketFactory()).build();
Backhand answered 10/12, 2013 at 10:12 Comment(3)
I believe http protocol is using PlainConnectionSocketFactory by default. I only registered https and the httpclient can still get plain HTTP URLs. so I don't think this step is necessary.Antedate
@Antedate it won't for PoolingHttpClientConnectionManagerMur
Thanks @migo.. I definitely needed both, in qa I deal with http, in production, it's httpsCalorimeter
B
18

After trying various options, following configuration worked for both http and https:

SSLContextBuilder builder = new SSLContextBuilder();
builder.loadTrustMaterial(null, new TrustSelfSignedStrategy());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                builder.build(), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

Registry<ConnectionSocketFactory> registry = RegistryBuilder. 
                 <ConnectionSocketFactory> create()
                .register("http", new PlainConnectionSocketFactory())
                .register("https", sslsf)
                .build();

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(2000);

CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setConnectionManager(cm)
                .build();

I am using http-client 4.3.3 : compile 'org.apache.httpcomponents:httpclient:4.3.3'

Bogart answered 7/8, 2014 at 16:6 Comment(1)
Thanks for providing a comprehensive, fully working example! I was hitting multiple issues with previous solutions and this helped immensely. Also helped that you provided the import statements, as there are multiple classes with the same names, adding to the confusion.Avaria
R
11

Simpler and shorter working code:

We are using HTTPClient 4.3.5 and we tried almost all solutions exist on the stackoverflow but nothing, After thinking and figuring out the problem, we come to the following code which works perfectly, just add it before creating HttpClient instance.

some method which you use to make post request...

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);

continue calling and using HttpPost instance in the normal form

Rosefish answered 3/4, 2015 at 15:36 Comment(2)
How we can post Data in headers? If we did, then see HTTP/1.1 400 Bad RequestEmpale
Works with 4.5, thanks! (though using a ton of deprecated stuff LOL)Martinelli
D
7

Here's a working distillation of the above techniques, equivalent to "curl --insecure":

HttpClient getInsecureHttpClient() throws GeneralSecurityException {
    TrustStrategy trustStrategy = new TrustStrategy() {
        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) {
            return true;
        }
    };

    HostnameVerifier hostnameVerifier = new HostnameVerifier() {
        @Override
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    };

    return HttpClients.custom()
            .setSSLSocketFactory(new SSLConnectionSocketFactory(
                    new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(),
                    hostnameVerifier))
            .build();
}
Dvina answered 5/12, 2016 at 20:2 Comment(0)
H
6

When using http client 4.5 I had to use the javasx.net.ssl.HostnameVerifier to allow any hostname (for testing purposes). Here is what I ended up doing:

CloseableHttpClient httpClient = null;
    try {
        SSLContextBuilder sslContextBuilder = new SSLContextBuilder();
        sslContextBuilder.loadTrustMaterial(null, new TrustSelfSignedStrategy());

        HostnameVerifier hostnameVerifierAllowAll = new HostnameVerifier() 
            {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };

        SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);

        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
            new AuthScope("192.168.30.34", 8443),
            new UsernamePasswordCredentials("root", "password"));

        httpClient = HttpClients.custom()
            .setSSLSocketFactory(sslSocketFactory)
            .setDefaultCredentialsProvider(credsProvider)
            .build();

        HttpGet httpGet = new HttpGet("https://192.168.30.34:8443/axis/services/getStuff?firstResult=0&maxResults=1000");

        CloseableHttpResponse response = httpClient.execute(httpGet);

        int httpStatus = response.getStatusLine().getStatusCode();
        if (httpStatus >= 200 && httpStatus < 300) { [...]
        } else {
            throw new ClientProtocolException("Unexpected response status: " + httpStatus);
        }

    } catch (Exception ex) {
        ex.printStackTrace();
    }
    finally {
        try {
            httpClient.close();
        } catch (IOException ex) {
            logger.error("Error while closing the HTTP client: ", ex);
        }
    }
Hinshaw answered 25/1, 2016 at 11:41 Comment(2)
Implementation of HostnameVerifier solved the problem for HTTPClient 4.5.Boliviano
for those who loves lambdas (JDK1.8), can replace SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll); with SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. It avoid anonymous class and makes code a little more readable.Linettelineup
I
4
class ApacheHttpClient {

    /***
     * This is a https get request that bypasses certificate checking and hostname verifier.
     * It uses basis authentication method.
     * It is tested with Apache httpclient-4.4.
     * It dumps the contents of a https page on the console output.
     * It is very similar to http get request, but with the additional customization of
     *   - credential provider, and
     *   - SSLConnectionSocketFactory to bypass certification checking and hostname verifier.
     * @param path String
     * @param username String
     * @param password String
     * @throws IOException
     */
    public void get(String path, String username, String password) throws IOException {
        final CloseableHttpClient httpClient = HttpClients.custom()
                .setDefaultCredentialsProvider(createCredsProvider(username, password))
                .setSSLSocketFactory(createGenerousSSLSocketFactory())
                .build();

        final CloseableHttpResponse response = httpClient.execute(new HttpGet(path));
        try {
            HttpEntity entity = response.getEntity();
            if (entity == null)
                return;
            System.out.println(EntityUtils.toString(entity));
        } finally {
            response.close();
            httpClient.close();
        }
    }

    private CredentialsProvider createCredsProvider(String username, String password) {
        CredentialsProvider credsProvider = new BasicCredentialsProvider();
        credsProvider.setCredentials(
                AuthScope.ANY,
                new UsernamePasswordCredentials(username, password));
        return credsProvider;
    }

    /***
     * 
     * @return SSLConnectionSocketFactory that bypass certificate check and bypass HostnameVerifier
     */
    private SSLConnectionSocketFactory createGenerousSSLSocketFactory() {
        SSLContext sslContext;
        try {
            sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, new TrustManager[]{createGenerousTrustManager()}, new SecureRandom());
        } catch (KeyManagementException | NoSuchAlgorithmException e) {
            e.printStackTrace();
            return null;
        }
        return new SSLConnectionSocketFactory(sslContext, NoopHostnameVerifier.INSTANCE);
    }

    private X509TrustManager createGenerousTrustManager() {
        return new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(X509Certificate[] cert, String s) throws CertificateException {
            }

            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
    }
}
Intended answered 4/12, 2014 at 23:31 Comment(0)
T
4

If you are using HttpClient 4.5.x, your code can be similar to the following:

SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null,
        TrustSelfSignedStrategy.INSTANCE).build();
SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(
        sslContext, NoopHostnameVerifier.INSTANCE);

HttpClient httpClient = HttpClients.custom()
                                   .setDefaultCookieStore(new BasicCookieStore())
                                   .setSSLSocketFactory(sslSocketFactory)
                                   .build();
Toponymy answered 22/3, 2018 at 22:42 Comment(1)
Did not work for me. I am using HttpClient:4.5.5. and HttpCore 4.4.9Pricillaprick
V
3

On top of PoolingHttpClientConnectionManager along with Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); If you want an asynchronous httpclient using PoolingNHttpClientConnectionManager the code shoudl be similar to following

SSLContextBuilder builder = SSLContexts.custom();
builder.loadTrustMaterial(null, new TrustStrategy() {
    @Override
    public boolean isTrusted(X509Certificate[] chain, String authType)
            throws CertificateException {
        return true;
    }
});
SSLContext sslContext = builder.build();
SchemeIOSessionStrategy sslioSessionStrategy = new SSLIOSessionStrategy(sslContext, 
                new HostnameVerifier(){
            @Override
            public boolean verify(String hostname, SSLSession session) {
                return true;// TODO as of now allow all hostnames
            }
        });
Registry<SchemeIOSessionStrategy> sslioSessionRegistry = RegistryBuilder.<SchemeIOSessionStrategy>create().register("https", sslioSessionStrategy).build();
PoolingNHttpClientConnectionManager ncm  = new PoolingNHttpClientConnectionManager(new DefaultConnectingIOReactor(),sslioSessionRegistry);
CloseableHttpAsyncClient asyncHttpClient = HttpAsyncClients.custom().setConnectionManager(ncm).build();
asyncHttpClient.start();        
Voronezh answered 19/2, 2016 at 9:19 Comment(0)
C
2

(I would have added a comment directly to vasekt's answer but I don't have enough reputation points (not sure the logic there)

Anyway... what I wanted to say is that even if you aren't explicitly creating/asking for a PoolingConnection, doesn't mean you aren't getting one.

I was going crazy trying to figure out why the original solution didn't work for me, but I ignored vasekt's answer as it "didn't apply to my case" - wrong!

I was staring at my stack-trace when low and behold I saw a PoolingConnection in the middle of it. Bang - I tired his addition and success!! (our demo is tomorrow and I was getting desperate) :-)

Cuboid answered 11/12, 2013 at 20:12 Comment(0)
F
2

Trust All Certs in Apache HTTP Client

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

          try {
                SSLContext sc = SSLContext.getInstance("SSL");
                sc.init(null, trustAllCerts, new java.security.SecureRandom());
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                        sc);
                httpclient = HttpClients.custom().setSSLSocketFactory(
                        sslsf).build();
                HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
Ferity answered 16/2, 2016 at 23:58 Comment(1)
This worked well with httpclient 4.5.9 , Just copy and paste the whole content that's it.Flacon
C
1

You can use following code snippet for get the HttpClient instance without ssl certification checking.

private HttpClient getSSLHttpClient() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {

        LogLoader.serverLog.trace("In getSSLHttpClient()");

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

        TrustManager tm = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            }

            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };

        context.init(null, new TrustManager[] { tm }, null);

        HttpClientBuilder builder = HttpClientBuilder.create();
        SSLConnectionSocketFactory sslConnectionFactory = new SSLConnectionSocketFactory(context);
        builder.setSSLSocketFactory(sslConnectionFactory);

        PlainConnectionSocketFactory plainConnectionSocketFactory = new PlainConnectionSocketFactory();
        Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
                .register("https", sslConnectionFactory).register("http", plainConnectionSocketFactory).build();

        PoolingHttpClientConnectionManager ccm = new PoolingHttpClientConnectionManager(registry);
        ccm.setMaxTotal(BaseConstant.CONNECTION_POOL_SIZE);
        ccm.setDefaultMaxPerRoute(BaseConstant.CONNECTION_POOL_SIZE);
        builder.setConnectionManager((HttpClientConnectionManager) ccm);

        builder.disableRedirectHandling();

        LogLoader.serverLog.trace("Out getSSLHttpClient()");

        return builder.build();
    }
Colosseum answered 13/3, 2018 at 17:19 Comment(0)
C
0

Slight tweak to answer from @divbyzero above to fix sonar security warnings

CloseableHttpClient getInsecureHttpClient() throws GeneralSecurityException {
            TrustStrategy trustStrategy = (chain, authType) -> true;

            HostnameVerifier hostnameVerifier = (hostname, session) -> hostname.equalsIgnoreCase(session.getPeerHost());

            return HttpClients.custom()
                    .setSSLSocketFactory(new SSLConnectionSocketFactory(new SSLContextBuilder().loadTrustMaterial(trustStrategy).build(), hostnameVerifier))
                    .build();
        }
Carisa answered 30/1, 2020 at 11:46 Comment(0)
M
0

Initially, i was able to disable for localhost using trust strategy, later i added NoopHostnameVerifier. Now it will work for both localhost and any machine name

SSLContext sslContext = SSLContextBuilder.create().loadTrustMaterial(null, new TrustStrategy() {

            @Override
            public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
                return true;
            }

        }).build();
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(
                sslContext, NoopHostnameVerifier.INSTANCE);
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
Meseems answered 4/5, 2020 at 7:41 Comment(0)
B
0

In java 11 or later if you want to skip certificate validation just try the following its working.

For HttpClient am using java's default client with this import java.net.http.HttpClient;

    static SSLContext insecureContext() {
    TrustManager[] noopTrustManager = new TrustManager[]{
            new X509TrustManager() {
                public void checkClientTrusted(X509Certificate[] xcs, String string) {}
                public void checkServerTrusted(X509Certificate[] xcs, String string) {}
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
            }
    };
    try {
        SSLContext sc = SSLContext.getInstance("ssl");
        sc.init(null, noopTrustManager, null);
        return sc;
    } catch (KeyManagementException | NoSuchAlgorithmException ex) {
        return null;
    }
}

and then make you HttpClient like this

HttpClient client = HttpClient.newBuilder()
            .sslContext(insecureContext())
            .build();
Buller answered 30/1, 2023 at 11:30 Comment(0)
H
0

I am using HttpClient 4.5.x, and the following code snippet worked for me:

public CloseableHttpClient client = HttpClientBuilder.create().disableRedirectHandling().build();
public CloseableHttpClient sslAcceptCerts() {
       TrustStrategy acceptingTrustStrategy = (cert, authType) -> true;
       SSLContext sslContext;
       try {
           sslContext = SSLContexts.custom().loadTrustMaterial(null, acceptingTrustStrategy).build();
       } catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) {
           throw new RuntimeException(e);
       }
       SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,
               NoopHostnameVerifier.INSTANCE);

       Registry<ConnectionSocketFactory> socketFactoryRegistry =
               RegistryBuilder.<ConnectionSocketFactory>create()
                       .register("https", sslsf)
                       .register("http", new PlainConnectionSocketFactory())
                       .build();

       BasicHttpClientConnectionManager connectionManager =
               new BasicHttpClientConnectionManager(socketFactoryRegistry);
       return client = HttpClients.custom().setSSLSocketFactory(sslsf)
               .setConnectionManager(connectionManager).build();
   }
Homunculus answered 7/11, 2023 at 2:11 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.