Ignorieren des SSL-Zertifikats in Apache HttpClient 4.3

102

Wie ignoriere ich das SSL-Zertifikat (vertraue allen) für Apache HttpClient 4.3 ?

Alle Antworten, die ich auf SO gefunden habe, behandeln frühere Versionen, und die API wurde geändert.

Verbunden:

Bearbeiten:

  • Es ist nur zu Testzwecken. Kinder, probieren Sie es nicht zu Hause (oder in der Produktion)
Jakub M.
quelle

Antworten:

146

Der folgende Code dient zum Vertrauen in selbstsignierte Zertifikate. Sie müssen die TrustSelfSignedStrategy verwenden, wenn Sie Ihren Client erstellen:

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

Das habe ich nicht SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERabsichtlich aufgenommen: Es ging darum, das Testen mit selbstsignierten Zertifikaten zuzulassen, damit Sie kein ordnungsgemäßes Zertifikat von einer Zertifizierungsstelle erwerben müssen. Sie können problemlos ein selbstsigniertes Zertifikat mit dem richtigen Hostnamen erstellen. Führen Sie dies aus, anstatt das SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERFlag hinzuzufügen .

mavroprovato
quelle
8
Ich musste dem Konstruktor das Argument SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER hinzufügen, damit dies mit dem HttpClientBuilder funktioniert (wie in der Antwort von holmis83 auf vasekt erwähnt).
Dejuknow
Siehe auch das Beispiel auf der httpclient-Website hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/…
arajashe
2
Ich musste auch ALLOW_ALL_HOSTNAME_VERIFIER verwenden: SSLConnectionSocketFactory (builder.build (), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Anzeigename
Dieser Code funktioniert für mich ohne Verwendung eines veralteten Konstruktors mit ArgumentSSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
user11153
Ich wünschte, Sie hätten die vollständige Referenz der von Ihnen verwendeten Klasse angegeben. Mehrere aufgerufene Klassen SSLContextBuilderwerden von Idea gefunden.
MasterMind
91

Wenn Sie die oben beschriebene Prozedur PoolingHttpClientConnectionManager nicht verwenden, wird der benutzerdefinierte SSLContext ignoriert. Sie müssen socketFactoryRegistry im Konstruktor übergeben, wenn Sie PoolingHttpClientConnectionManager erstellen.

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();
vasekt
quelle
11
Anstatt Ihren eigenen X509HostnameVerifier zu erstellen, können Sie SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER verwenden.
holmis83
Wie unten mit @ rich95 markiert, erhalten Sie für HttpClients standardmäßig einen PoolingHttpClient. Dies ist daher sehr häufig relevant. Ich musste einige dieser Antworten ausprobieren, bevor ich herausfand, dass ich sie brauchte.
SunSear
1
Es wurde versucht, dies auf WebSphere anzuwenden, und es wurde "java.security.KeyStoreException: IBMTrustManager: Problem beim Zugriff auf den Trust Store java.io.IOException: Ungültiges Keystore-Format" angezeigt. Um zu vermeiden, dass Sie den KeyStore übergeben müssen statt null zu builder.loadTrustMaterial
Georgy Gobozov
1
Mit HttpClient 4.5 funktionieren beide HttpClients.custom().setConnectionManager(cm).build()und HttpClients.custom().setSSLSocketFactory(connectionFactory).build()funktionieren, sodass Sie keinePoolingHttpClientConnectionManager
soulmachine
Verwendung von PoolingHttpClientConnectionManager nach dem Erstellen dieses Codes funktioniert mein Code, aber ich möchte wissen, ob das Verbindungspooling funktioniert oder nicht
Labeo
34

Wenn Sie zusätzlich zur Antwort von @mavroprovato allen Zertifikaten vertrauen möchten, anstatt nur selbstsigniert zu sein, tun Sie dies (im Stil Ihres Codes).

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

oder (direktes Kopieren und Einfügen aus meinem eigenen 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();

Und wenn Sie auch die Überprüfung des Hostnamens überspringen möchten, müssen Sie festlegen

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

auch. (ALLOW_ALL_HOSTNAME_VERIFIER ist veraltet).

Obligatorische Warnung: Sie sollten dies nicht wirklich tun. Das Akzeptieren aller Zertifikate ist eine schlechte Sache. Es gibt jedoch einige seltene Anwendungsfälle, in denen Sie dies tun möchten.

Als Hinweis auf den zuvor angegebenen Code möchten Sie die Antwort auch dann schließen, wenn httpclient.execute () eine Ausnahme auslöst

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

Der obige Code wurde mit getestet

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

Und für Interessierte ist hier mein vollständiger Testsatz:

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

(Arbeitstestprojekt in Github )

eis
quelle
1
HttpClient # execute gibt im Falle einer Ausnahme niemals ein Null-Antwortobjekt zurück. Darüber hinaus gewährleisten Standard-HttpClient-Implementierungen die automatische Freigabe aller Systemressourcen, z. B. geleaster Verbindungen, im Falle einer Ausnahme während der Anforderungsausführung. Die von mavroprovato verwendete Ausnahmebehandlung ist vollkommen ausreichend.
OK2C
@oleg Der Punkt der Closable-Schnittstelle besteht darin, "[...] Stream zu schließen und alle damit verbundenen Systemressourcen freizugeben. Wenn der Stream bereits geschlossen ist, hat das Aufrufen dieser Methode keine Auswirkung." Daher ist es empfehlenswert, es auch dann zu verwenden, wenn es nicht benötigt wird. Außerdem verstehe ich den Kommentar zur Rückgabe einer Nullantwort nicht - natürlich nicht, wenn es eine Ausnahme auslöst, gibt es nichts zurück?
Eis
1
Apache Httpclient nie jemals ein auf null oder teilweise initialisiert Antwortobjekt. Dies hat nichts damit zu tun, wie oft #close aufgerufen wird, sondern mit einer völlig unnötigen
Nullprüfung
@oleg und der von mir angegebene Code geht niemals davon aus, dass er ein null oder teilweise initialisiertes Antwortobjekt zurückgibt oder sogar einen solchen Fall überprüft. Ich habe keine Ahnung, wovon du sprichst?
uvb
1
[ seufz ] was völlig unnötig ist, da HttpResponse niemals null sein kann und im Falle einer Ausnahme die # execute-Methode beendet wird, ohne eine Antwort zurückzugeben ;-)
ok2c
22

Eine kleine Ergänzung zur Antwort von vasekt:

Die mit der SocketFactoryRegistry bereitgestellte Lösung funktioniert bei Verwendung von PoolingHttpClientConnectionManager.

Verbindungen über einfaches http funktionieren dann jedoch nicht mehr. Sie müssen zusätzlich eine PlainConnectionSocketFactory für das http-Protokoll hinzufügen, damit sie wieder funktionieren:

Registry<ConnectionSocketFactory> socketFactoryRegistry = 
  RegistryBuilder.<ConnectionSocketFactory> create()
  .register("https", sslsf)
  .register("http", new PlainConnectionSocketFactory()).build();
migo
quelle
Ich glaube, das httpProtokoll wird PlainConnectionSocketFactory standardmäßig verwendet. Ich habe mich nur registriert httpsund die httpclientkönnen immer noch einfache HTTP-URLs erhalten. Daher halte ich diesen Schritt nicht für notwendig.
Soulmachine
@soulmachine wird es nicht fürPoolingHttpClientConnectionManager
amseager
15

Nachdem Sie verschiedene Optionen ausprobiert hatten, funktionierte die folgende Konfiguration sowohl für http als auch für 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();

Ich benutze http-client 4.3.3 -

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

Saurabh
quelle
1
Vielen Dank für ein umfassendes, voll funktionsfähiges Beispiel! Ich hatte mehrere Probleme mit früheren Lösungen und dies hat immens geholfen. Es hat auch geholfen, dass Sie die Importanweisungen bereitgestellt haben, da es mehrere Klassen mit demselben Namen gibt, was die Verwirrung noch verstärkt.
Helmy
8

Einfacherer und kürzerer Arbeitscode:

Wir verwenden HTTPClient 4.3.5 und haben versucht, dass fast alle Lösungen im Stackoverflow vorhanden sind, aber nichts. Nachdem wir das Problem überlegt und herausgefunden haben, kommen wir zu dem folgenden Code, der perfekt funktioniert. Fügen Sie ihn einfach hinzu, bevor Sie eine HttpClient-Instanz erstellen.

eine Methode, mit der Sie eine Post-Anfrage stellen ...

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

Rufen Sie die HttpPost-Instanz weiterhin in der normalen Form auf und verwenden Sie sie

Hamed MP
quelle
Wie können wir Daten in Headern veröffentlichen? Wenn wir das getan haben, dann sehen Sie HTTP / 1.1 400 Bad Request
6

Hier ist eine funktionierende Destillation der oben genannten Techniken, die "curl --insecure" entspricht:

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

Bei Verwendung von http client 4.5 musste ich den javasx.net.ssl.HostnameVerifier verwenden, um einen beliebigen Hostnamen zuzulassen (zu Testzwecken). Folgendes habe ich getan:

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);
        }
    }
Kurt
quelle
Die Implementierung von HostnameVerifier löste das Problem für HTTPClient 4.5.
digz6666
für diejenigen , die Lambda - Ausdrücke (JDK1.8) können liebt ersetzen SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);mit SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. Es vermeidet anonyme Klassen und macht Code ein wenig lesbarer.
Vielinko
3

Hinzu kommt PoolingHttpClientConnectionManagerzusammen mit Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); Wenn Sie eine asynchrone Httpclient verwenden PoolingNHttpClientConnectionManagerden Code shoudl ähnlich sein folgenden

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();        
Anant Laxmikant Bobde
quelle
3

Wenn Sie verwenden HttpClient 4.5.x, kann Ihr Code wie folgt aussehen:

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();
Paul Vargas
quelle
Hat bei mir nicht funktioniert. Ich benutze HttpClient: 4.5.5. und 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;
            }
        };
    }
}
Dahai Li
quelle
2

Vertrauen Sie allen Zertifikaten im 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());
Jeff Z.
quelle
Dies funktionierte gut mit httpclient 4.5.9. Kopieren Sie einfach den gesamten Inhalt und fügen Sie ihn ein.
Sathya
1

(Ich hätte einen Kommentar direkt zu Vasekts Antwort hinzugefügt, aber ich habe nicht genügend Reputationspunkte (nicht sicher, welche Logik dort vorhanden ist).

Wie auch immer ... was ich sagen wollte ist, dass selbst wenn Sie nicht explizit eine PoolingConnection erstellen / anfordern, dies nicht bedeutet, dass Sie keine bekommen.

Ich wurde verrückt, als ich versuchte herauszufinden, warum die ursprüngliche Lösung für mich nicht funktionierte, aber ich ignorierte die Antwort von vasekt, da sie "nicht auf meinen Fall zutraf" - falsch!

Ich starrte auf meine Stapelspur, als sie niedrig war, und siehe, ich sah eine PoolingConnection in der Mitte. Bang - ich habe seine Hinzufügung und seinen Erfolg satt !! (Unsere Demo ist morgen und ich wurde verzweifelt) :-)

rich95
quelle
0

Sie können das folgende Codefragment verwenden, um die HttpClient-Instanz ohne Überprüfung der SSL-Zertifizierung abzurufen.

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();
    }
Radadiya Nikunj
quelle
0

Eine leichte Änderung, um von @divbyzero oben zu antworten und Sonar-Sicherheitswarnungen zu beheben

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

Anfangs konnte ich localhost mithilfe der Vertrauensstrategie deaktivieren, später fügte ich NoopHostnameVerifier hinzu. Jetzt funktioniert es sowohl für localhost als auch für jeden Computernamen

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();
U_R_Naveen UR_Naveen
quelle