Ignorare il certificato SSL in Apache HttpClient 4.3


102

Come ignorare il certificato SSL (fidati di tutti) per Apache HttpClient 4.3 ?

Tutte le risposte che ho trovato su SO trattano le versioni precedenti e l'API è cambiata.

Relazionato:

Modificare:

  • È solo a scopo di test. Ragazzi, non provatelo a casa (o in produzione)

Risposte:


146

Il codice seguente funziona per considerare attendibili i certificati autofirmati. Devi usare TrustSelfSignedStrategy quando crei il tuo 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();
}

Non ho incluso lo SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERscopo: il punto era consentire il test con certificati autofirmati in modo da non dover acquisire un certificato appropriato da un'autorità di certificazione. Puoi facilmente creare un certificato autofirmato con il nome host corretto, quindi fallo invece di aggiungere il SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERflag.


8
Ho dovuto aggiungere l'argomento SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER al costruttore per farlo funzionare con HttpClientBuilder (come menzionato nella risposta di holmis83 a vasekt).
dejuknow


2
Ho anche dovuto usare ALLOW_ALL_HOSTNAME_VERIFIER: SSLConnectionSocketFactory (builder.build (), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Nome visualizzato

Questo codice funziona per me senza utilizzare il costruttore deprecato con argomentoSSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
user11153

Vorrei che tu avessi specificato il riferimento completo della classe che stavi utilizzando. Più classi chiamate SSLContextBuildervengono trovate da Idea.
MasterMind

91

Se si utilizza la procedura PoolingHttpClientConnectionManager precedente non funziona, SSLContext personalizzato viene ignorato. Devi passare socketFactoryRegistry nel costruttore durante la creazione di 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();

11
Invece di creare il tuo X509HostnameVerifier, puoi usare SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER.
holmis83

Come indicato di seguito da @ rich95, l'impostazione predefinita per HttpClients è di fornire un PoolingHttpClient, quindi questo è rilevante molto spesso. Ho dovuto provare alcune di queste risposte prima di scoprire che ne avevo bisogno.
SunSear

1
Ho provato ad applicarlo su WebSphere e ho ottenuto "java.security.KeyStoreException: IBMTrustManager: problema di accesso al truststore java.io.IOException: formato keystore non valido" Per evitare è necessario passare KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType ()); invece di null a builder.loadTrustMaterial
Georgy Gobozov

1
In realtà, con HttpClient 4.5, funzioneranno sia HttpClients.custom().setConnectionManager(cm).build()e HttpClients.custom().setSSLSocketFactory(connectionFactory).build(), quindi non è necessario creare unPoolingHttpClientConnectionManager
soulmachine

Come utilizzare PoolingHttpClientConnectionManager dopo averlo creato, il mio codice funziona ma voglio sapere se il pool di connessioni funziona o meno
Labeo

34

In aggiunta alla risposta di @mavroprovato, se vuoi fidarti di tutti i certificati invece che solo autofirmati, lo faresti (nello stile del tuo codice)

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

oppure (copia-incolla diretta dal mio codice):

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

E se vuoi saltare anche la verifica del nome host, devi impostare

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

anche. (ALLOW_ALL_HOSTNAME_VERIFIER è deprecato).

Avviso obbligatorio: non dovresti farlo davvero, accettare tutti i certificati è una brutta cosa. Tuttavia, ci sono alcuni rari casi d'uso in cui vuoi farlo.

Come nota al codice data in precedenza, ti consigliamo di chiudere la risposta anche se httpclient.execute () genera un'eccezione

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

Il codice sopra è stato testato utilizzando

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

E per gli interessati, ecco il mio set completo di test:

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

(progetto di test funzionante in GitHub )


1
HttpClient # execute non restituirà mai un oggetto di risposta null in caso di eccezione. Inoltre, le implementazioni HttpClient di serie garantiranno la deallocazione automatica di tutte le risorse di sistema come le connessioni in leasing in caso di eccezione durante l'esecuzione della richiesta. La gestione delle eccezioni utilizzata da mavroprovato è perfettamente adeguata.
ok2c

@oleg il punto dell'interfaccia Closable è "Chiudere [...] il flusso e rilasciare le risorse di sistema ad esso associate. Se il flusso è già chiuso, l'invocazione di questo metodo non ha alcun effetto." quindi è buona pratica usarlo anche se non sarebbe necessario. Inoltre, non capisco il commento di restituire una risposta nulla - ovviamente no, se genera un'eccezione, non restituisce nulla?
eis

1
Apache HttpClient non restituisce mai un oggetto di risposta null o parzialmente inizializzato. Questo non ha nulla a che fare con il numero di volte in cui #close viene richiamato, ma con un controllo nullo completamente inutile nella clausola finalmente
ok2c

@oleg e non fa mai il codice che ho dato presume che restituirebbe un oggetto di risposta nullo o parzialmente inizializzato, o addirittura controllerebbe un caso del genere. Non ho la più pallida idea di cosa stai parlando?
eis

1
[ sigh ] che è completamente inutile dato che HttpResponse non può mai essere nullo e in caso di eccezione il metodo #execute terminerà senza restituire una risposta ;-)
ok2c

22

Una piccola aggiunta alla risposta di vasekt:

La soluzione fornita con SocketFactoryRegistry funziona quando si usa PoolingHttpClientConnectionManager.

Tuttavia, le connessioni tramite http semplice non funzionano più allora. Devi aggiungere anche un PlainConnectionSocketFactory per il protocollo http per farli funzionare di nuovo:

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

Credo che il httpprotocollo utilizzi PlainConnectionSocketFactory per impostazione predefinita. Mi sono solo registrato httpse httpclientposso ancora ottenere semplici URL HTTP. quindi non credo che questo passaggio sia necessario.
soulmachine

@soulmachine non sarà perPoolingHttpClientConnectionManager
amseager

15

Dopo aver provato varie opzioni, la seguente configurazione ha funzionato sia per http che per 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);//max connection


        //System.setProperty("jsse.enableSNIExtension", "false"); //""
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(sslsf)
                .setConnectionManager(cm)
                .build();

Sto usando http-client 4.3.3 -

compile 'org.apache.httpcomponents:httpclient:4.3.3'


1
Grazie per aver fornito un esempio completo e completamente funzionante! Stavo riscontrando più problemi con le soluzioni precedenti e questo mi ha aiutato immensamente. Ha anche aiutato a fornire le istruzioni di importazione, poiché ci sono più classi con gli stessi nomi, aggiungendo confusione.
helmy

8

Codice di lavoro più semplice e più breve:

Stiamo usando HTTPClient 4.3.5 e abbiamo provato quasi tutte le soluzioni presenti nello stackoverflow ma niente, dopo aver pensato e individuato il problema, arriviamo al seguente codice che funziona perfettamente, basta aggiungerlo prima di creare l'istanza di HttpClient.

un metodo che usi per fare una richiesta di post ...

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

continuare a chiamare e utilizzare l'istanza HttpPost nella forma normale


Come possiamo inserire i dati nelle intestazioni? In

6

Ecco una distillazione funzionante delle tecniche precedenti, equivalente a "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();
}

5

Quando si utilizza il client http 4.5, ho dovuto utilizzare javasx.net.ssl.HostnameVerifier per consentire qualsiasi nome host (a scopo di test). Ecco cosa ho finito per fare:

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

L'implementazione di HostnameVerifier ha risolto il problema per HTTPClient 4.5.
digz6666

per chi ama lambda (JDK1.8), può sostituire SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);con SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. Evita la classe anonima e rende il codice un po 'più leggibile.
Vielinko

3

In cima PoolingHttpClientConnectionManagerinsieme a Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); Se si desidera un asincrono httpclient utilizzando PoolingNHttpClientConnectionManageril codice shoudl essere simile al seguente

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

3

Se stai usando HttpClient 4.5.x, il tuo codice può essere simile al seguente:

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

Non ha funzionato per me. Sto usando HttpClient: 4.5.5. e HttpCore 4.4.9
Vijay Kumar

2
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;
            }
        };
    }
}

2

Considera attendibili tutti i certificati nel client HTTP Apache

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

Funzionava bene con httpclient 4.5.9, basta copiare e incollare l'intero contenuto il gioco è fatto.
Satya,

1

(Avrei aggiunto un commento direttamente alla risposta di vasekt ma non ho abbastanza punti reputazione (non sono sicuro della logica lì)

Comunque ... quello che volevo dire è che anche se non stai creando / chiedendo esplicitamente una PoolingConnection, non significa che non ne stai ottenendo uno.

Stavo impazzendo cercando di capire perché la soluzione originale non funzionasse per me, ma ho ignorato la risposta di vasekt perché "non si applicava al mio caso" - sbagliato!

Stavo fissando il mio stack-trace quando è basso ed ecco ho visto una PoolingConnection nel mezzo di esso. Bang - ho stancato la sua aggiunta e il successo !! (la nostra demo è domani e stavo diventando disperato) :-)


0

Puoi utilizzare il seguente frammento di codice per ottenere l'istanza HttpClient senza il controllo della certificazione SSL.

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

0

Leggero aggiustamento per rispondere da @divbyzero sopra per correggere gli avvisi di sicurezza del sonar

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

0

Inizialmente, sono stato in grado di disabilitare per localhost utilizzando la strategia di fiducia, in seguito ho aggiunto NoopHostnameVerifier. Ora funzionerà sia per localhost che per qualsiasi nome di macchina

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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.