Ignorer le certificat SSL dans Apache HttpClient 4.3

102

Comment ignorer le certificat SSL (tout faire confiance) pour Apache HttpClient 4.3 ?

Toutes les réponses que j'ai trouvées sur SO traitent des versions précédentes, et l'API a changé.

En relation:

Éditer:

  • Ce n'est qu'à des fins de test. Les enfants, ne l'essayez pas à la maison (ou en production)
Jakub M.
la source

Réponses:

146

Le code ci-dessous fonctionne pour approuver les certificats auto-signés. Vous devez utiliser la TrustSelfSignedStrategy lors de la création de votre 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();
}

Je n'ai pas inclus SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERle but exprès: le but était d'autoriser les tests avec des certificats auto-signés afin que vous n'ayez pas à acquérir un certificat approprié auprès d'une autorité de certification. Vous pouvez facilement créer un certificat auto-signé avec le nom d'hôte correct, alors faites-le au lieu d'ajouter l' SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERindicateur.

mavroprovato
la source
8
J'ai dû ajouter l'argument SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER au constructeur pour que cela fonctionne avec HttpClientBuilder (comme mentionné dans la réponse de holmis83 à vasekt).
dejuknow
se référer également à l'exemple sur le site httpclient hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/…
arajashe
2
J'ai également dû utiliser ALLOW_ALL_HOSTNAME_VERIFIER: SSLConnectionSocketFactory (builder.build (), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Afficher le nom le
Ce code fonctionne pour moi sans utiliser de constructeur obsolète avec argumentSSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
user11153
J'aurais aimé que vous ayez spécifié la référence complète de la classe que vous utilisiez. Plusieurs classes appelées SSLContextBuildersont trouvées par Idea.
MasterMind
91

Si vous utilisez la procédure PoolingHttpClientConnectionManager ci-dessus ne fonctionne pas, SSLContext personnalisé est ignoré. Vous devez passer socketFactoryRegistry dans contructor lors de la création de 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();
vasekt
la source
11
Au lieu de créer votre propre X509HostnameVerifier, vous pouvez utiliser SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER.
holmis83
Comme indiqué ci-dessous par @ rich95, la valeur par défaut pour HttpClients est de vous donner un PoolingHttpClient, c'est donc très souvent pertinent. J'ai dû essayer plusieurs de ces réponses avant de constater que j'avais besoin de cela.
SunSear
1
J'ai essayé de l'appliquer sur WebSphere et j'ai obtenu "java.security.KeyStoreException: IBMTrustManager: Problème d'accès au magasin de confiance java.io.IOException: Format de fichier de clés non valide" Pour éviter de passer KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultType ()); au lieu de null pour builder.loadTrustMaterial
Georgy Gobozov
1
En fait, avec HttpClient 4.5, les deux HttpClients.custom().setConnectionManager(cm).build()et HttpClients.custom().setSSLSocketFactory(connectionFactory).build()fonctionneront, vous n'avez donc pas besoin de créer unPoolingHttpClientConnectionManager
soulmachine
Comment utiliser PoolingHttpClientConnectionManager après avoir créé cela, mon code fonctionne mais je veux savoir si le regroupement de connexions fonctionne ou non
Labeo
34

En plus de la réponse de @mavroprovato, si vous voulez faire confiance à tous les certificats au lieu de simplement auto-signés, vous le feriez (dans le style de votre code)

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

ou (copier-coller direct à partir de mon propre 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();

Et si vous souhaitez également ignorer la vérification du nom d'hôte, vous devez définir

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

ainsi que. (ALLOW_ALL_HOSTNAME_VERIFIER est obsolète).

Avertissement obligatoire: vous ne devriez pas vraiment faire cela, accepter tous les certificats est une mauvaise chose. Cependant, il existe de rares cas d'utilisation où vous souhaitez le faire.

Comme note au code précédemment donné, vous voudrez fermer la réponse même si httpclient.execute () lève une 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();
    }
}

Le code ci-dessus a été testé en utilisant

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

Et pour les intéressés, voici mon ensemble de tests complet:

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

(projet de test de travail dans github )

eis
la source
1
HttpClient # execute ne retournera jamais un objet de réponse nul en cas d'exception. De plus, les implémentations de stock HttpClient assureront la désallocation automatique de toutes les ressources système telles que les connexions louées en cas d'exception lors de l'exécution de la requête. La gestion des exceptions utilisée par mavroprovato est parfaitement adéquate.
ok2c
@oleg le but de l' interface Closable est de "Fermer [...] le flux et libérer toutes les ressources système qui lui sont associées. Si le flux est déjà fermé, l'appel de cette méthode n'a aucun effet." il est donc recommandé de l'utiliser même si ce n'est pas nécessaire. De plus, je ne comprends pas le commentaire du retour de la réponse nulle - bien sûr que non, s'il lève une exception, il ne renvoie rien?
eis
1
Apache HttpClient ne retourne jamais un objet de réponse nul ou partiellement initialisé. Cela n'a rien à voir avec le nombre de fois où #close est invoqué, mais plutôt une vérification null complètement inutile dans la clause
finally
@oleg et le code que j'ai donné ne suppose jamais qu'il renverrait un objet de réponse nul ou partiellement initialisé, ni même vérifierait un tel cas. Je ne sais pas de quoi tu parles?
eis
1
[ soupir ] ce qui est complètement inutile étant donné que HttpResponse ne peut jamais être nul et en cas d'exception la méthode #execute se terminera sans renvoyer de réponse ;-)
ok2c
22

Un petit ajout à la réponse de vasekt:

La solution fournie avec SocketFactoryRegistry fonctionne lors de l'utilisation de PoolingHttpClientConnectionManager.

Cependant, les connexions via http simple ne fonctionnent plus alors. Vous devez ajouter un PlainConnectionSocketFactory pour le protocole http en plus pour les faire fonctionner à nouveau:

Registry<ConnectionSocketFactory> socketFactoryRegistry = 
  RegistryBuilder.<ConnectionSocketFactory> create()
  .register("https", sslsf)
  .register("http", new PlainConnectionSocketFactory()).build();
migo
la source
Je crois que le httpprotocole utilise PlainConnectionSocketFactory par défaut. Je ne me suis inscrit que httpset je httpclientpeux toujours obtenir des URL HTTP simples. donc je ne pense pas que cette étape soit nécessaire.
soulmachine le
@soulmachine il ne sera pas pourPoolingHttpClientConnectionManager
amseager
15

Après avoir essayé diverses options, la configuration suivante a fonctionné pour http et 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();

J'utilise http-client 4.3.3 -

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

Saurabh
la source
1
Merci d'avoir fourni un exemple complet et pleinement fonctionnel! Je rencontrais plusieurs problèmes avec les solutions précédentes et cela a énormément aidé. Nous avons également aidé à fournir les instructions d'importation, car il existe plusieurs classes portant les mêmes noms, ce qui ajoute à la confusion.
helmy
8

Code de travail plus simple et plus court:

Nous utilisons HTTPClient 4.3.5 et nous avons essayé presque toutes les solutions existent sur le stackoverflow mais rien, après avoir réfléchi et compris le problème, nous arrivons au code suivant qui fonctionne parfaitement, il suffit de l'ajouter avant de créer l'instance HttpClient.

une méthode que vous utilisez pour faire une demande de publication ...

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

continuer à appeler et à utiliser l'instance HttpPost sous la forme normale

Hamed MP
la source
Comment publier des données dans les en-têtes? Si nous l'avons fait, alors voir HTTP / 1.1 400 Bad Request
6

Voici une distillation fonctionnelle des techniques ci-dessus, équivalente à "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();
}
divbyzero
la source
5

Lors de l'utilisation du client http 4.5, j'ai dû utiliser javasx.net.ssl.HostnameVerifier pour autoriser n'importe quel nom d'hôte (à des fins de test). Voici ce que j'ai fini par faire:

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
la source
L'implémentation de HostnameVerifier a résolu le problème de HTTPClient 4.5.
digz6666
pour ceux qui aiment les lambdas (JDK1.8), peuvent remplacer SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);par SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. Cela évite les classes anonymes et rend le code un peu plus lisible.
Vielinko
3

En plus de PoolingHttpClientConnectionManagerlong avec Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); Si vous souhaitez un asynchrone httpclient en utilisant PoolingNHttpClientConnectionManagerle code shoudl similaire à la suite

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
la source
3

Si vous utilisez HttpClient 4.5.x, votre code peut être similaire à ce qui suit:

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
la source
N'a pas travaillé pour moi. J'utilise HttpClient: 4.5.5. et 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
la source
2

Faire confiance à tous les certificats dans le 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());
Jeff Z
la source
Cela a bien fonctionné avec httpclient 4.5.9, copiez et collez simplement tout le contenu.
sathya le
1

(J'aurais ajouté un commentaire directement à la réponse de vasekt mais je n'ai pas assez de points de réputation (je ne suis pas sûr de la logique)

Quoi qu'il en soit ... ce que je voulais dire, c'est que même si vous ne créez pas / ne demandez pas explicitement un PoolingConnection, cela ne signifie pas que vous n'en obtenez pas.

Je devenais fou en essayant de comprendre pourquoi la solution originale ne fonctionnait pas pour moi, mais j'ai ignoré la réponse de vasekt car elle "ne s'appliquait pas à mon cas" - faux!

Je regardais ma trace de pile quand j'étais bas et voici, j'ai vu un PoolingConnection au milieu. Bang - J'ai fatigué son ajout et son succès !! (notre démo est demain et je devenais désespéré) :-)

riche95
la source
0

Vous pouvez utiliser l'extrait de code suivant pour obtenir l'instance HttpClient sans vérification de certification 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();
    }
Radadiya Nikunj
la source
0

Légère modification de la réponse de @divbyzero ci-dessus pour corriger les avertissements de sécurité du sondeur

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
la source
0

Au départ, j'ai pu désactiver pour localhost en utilisant la stratégie de confiance, plus tard j'ai ajouté NoopHostnameVerifier. Maintenant, cela fonctionnera à la fois pour l'hôte local et pour tout nom de machine

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
la source