Ігнорування сертифікату SSL в Apache HttpClient 4.3


102

Як ігнорувати сертифікат SSL (довіряйте всім) для Apache HttpClient 4.3 ?

Усі відповіді, які я знайшов на SO, стосуються попередніх версій, і API змінився.

Пов'язані:

Редагувати:

  • Це лише для тестових цілей. Діти, не спробуйте цього вдома (або на виробництві)

Відповіді:


146

Код нижче працює для довіри сертифікатам, що підписуються самостійно. Ви повинні використовувати TrustSelfSignedStrategy при створенні свого клієнта:

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

Я не включав SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERцілеспрямовано: Справа в тому, щоб дозволити тестувати сертифікати, що підписуються самостійно, тому вам не доведеться купувати належний сертифікат від сертифікаційного органу. Ви можете легко створити самопідписаний сертифікат з правильним іменем хоста, тому зробіть це замість того, щоб додавати SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIERпрапор.


8
Мені довелося додати аргумент SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER до конструктора, щоб змусити це працювати з HttpClientBuilder (про що йдеться у відповіді holmis83 на васект).
dejuknow

також посилайтесь на приклад на веб-сайті httpclient hc.apache.org/httpcomponents-client-4.3.x/httpclient/examples/…
arajashe

2
Я також повинен був використовувати ALLOW_ALL_HOSTNAME_VERIFIER: SSLConnectionSocketFactory (builder.build (), SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Відображувати ім’я

Цей код працює для мене без використання застарілого конструктора з аргументомSSLConnectionSocketFactory.ALLOW_‌​ALL_HOSTNAME_VERIFIER
user11153

Я хотів би, щоб ви вказали повне посилання на клас, який ви використовували. SSLContextBuilderІдея знаходить кілька названих класів .
MasterMind

91

Якщо ви використовуєте PoolingHttpClientConnectionManager, описана вище процедура не працює, спеціальний SSLContext ігнорується. При створенні PoolingHttpClientConnectionManager ви повинні передати socketFactoryRegistry в кондуктор.

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
Замість створення власного X509HostnameVerifier ви можете використовувати SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER.
holmis83

Як зазначено нижче @ rich95, типовим для HttpClients є надання PoolingHttpClient, тому це актуально дуже часто. Мені довелося спробувати досить багато таких відповідей, перш ніж виявити, що мені це потрібно.
SunSear

1
Спробував застосувати це на WebSphere і отримав "java.security.KeyStoreException: IBMTrustManager: Проблема з доступом до довіреного магазину java.io.IOException: Неправильний формат зберігання ключів" Щоб уникнути необхідності передачі KeyStore trustStore = KeyStore.getInstance (KeyStore.getDefaultTypeTypeType) замість null to builder.loadTrustMaterial
Георгій

1
Власне, з HttpClient 4.5 і те, HttpClients.custom().setConnectionManager(cm).build()і інше HttpClients.custom().setSSLSocketFactory(connectionFactory).build()буде працювати, тому вам не потрібно створюватиPoolingHttpClientConnectionManager
soulmachine

Як користуватися PoolingHttpClientConnectionManager після його створення, мій код працює, але я хочу знати, чи працює об'єднання з'єднань чи ні
Labeo

34

Як додаток до відповіді @mavroprovato, якщо ви хочете довіряти всім сертифікатам, а не лише самопідписаним, ви зробите це (у стилі свого коду)

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

або (пряма копія-вставка з мого власного коду):

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

І якщо ви також хочете пропустити перевірку імені хоста, вам потрібно встановити

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

також. (ALLOW_ALL_HOSTNAME_VERIFIER застаріло).

Обов’язкове попередження: ви насправді цього не повинні робити, прийняття всіх сертифікатів - це погано. Однак є деякі рідкісні випадки використання, коли ви хочете це зробити.

Як попередньо надану примітку до коду, ви хочете закрити відповідь, навіть якщо httpclient.execute () видає виняток

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

Код вище було випробувано за допомогою

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

А для зацікавлених, ось мій повний тестовий набір:

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

(робочий тестовий проект у Github )


1
HttpClient # Execute ніколи не поверне об’єкт нульової відповіді у разі винятку. Більше того, біржові реалізації HttpClient забезпечать автоматичне розміщення всіх системних ресурсів, таких як орендовані з'єднання, у випадку винятку під час виконання запиту. Обробка винятків, що використовується мавропровато, цілком адекватна.
ok2c

@oleg сенсом інтерфейсу, що закривається, є "Закрити потік [...] та звільнити будь-які системні ресурси, пов'язані з ним. Якщо потік уже закритий, то виклик цього методу не впливає". тому найкраще використовувати його, навіть якщо це не знадобиться. Крім того, я не розумію коментар повернення нульової відповіді - звичайно, це не так, якщо він викидає виняток, він нічого не повертає?
eis

1
Apache HttpClient ніколи не повертає нульовий або частково ініціалізований об'єкт відповіді. Це не має нічого спільного з тим, скільки разів викликається #close, а зовсім непотрібна перевірка нуля в остаточному пункті
ok2c

@oleg і ніколи код, який я дав, припускає, що він поверне нульовий або частково ініціалізований об'єкт відповіді або навіть перевірить такий випадок. У мене немає поняття, про що ти говориш?
eis

1
[ зітхання ], що зовсім непотрібно, враховуючи, що HttpResponse ніколи не може бути нульовим, а у випадку винятку метод #execute припиняється, не повертаючи відповідь ;-)
ok2c

22

Невелике доповнення до відповіді від vasekt:

Надане рішення з SocketFactoryRegistry працює при використанні PoolingHttpClientConnectionManager.

Однак з'єднання через звичайний http тоді вже не працюють. Вам потрібно додатково додати PlainConnectionSocketFactory для протоколу http, щоб вони знову працювали:

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

Я вважаю, що httpпротокол використовується PlainConnectionSocketFactory за замовчуванням. Я лише зареєструвався httpsі httpclientвсе ще можу отримати звичайні URL-адреси HTTP. тому я не думаю, що цей крок необхідний.
soulmachine

@soulmachine це не будеPoolingHttpClientConnectionManager
amseager

15

Спробувавши різні параметри, наступна конфігурація працювала і для http, і для 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();

Я використовую http-клієнт 4.3.3 -

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


1
Дякуємо, що надали всебічний, повноцінний приклад! Я торкався декількох проблем із попередніми рішеннями, і це дуже допомогло. Також допомогло, що ви надали заяви про імпорт, оскільки є кілька класів з однаковими іменами, додаючи до плутанини.
helmy

8

Простіший і коротший робочий код:

Ми використовуємо HTTPClient 4.3.5, і ми намагалися майже всі рішення існувати на stackoverflow, але нічого. Після роздумів і з'ясування проблеми ми переходимо до наступного коду, який ідеально працює, просто додамо його до створення екземпляра HttpClient.

якийсь метод, який ви використовуєте для оформлення запиту на пошту ...

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

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

    HttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslSF).build();
    HttpPost postRequest = new HttpPost(url);

продовжуйте дзвонити та використовувати екземпляр HttpPost у звичайній формі


Як ми можемо розміщувати дані в заголовках? Якщо ми це зробили, то дивіться HTTP / 1.1 400 Поганий запит

6

Ось робоча перегонка вищевказаних методик, еквівалентна "завитка - незахищеність":

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

Під час використання клієнта http 4.5 мені довелося використовувати javasx.net.ssl.HostnameVerifier, щоб дозволити будь-яке ім'я хоста (для тестування). Ось що я закінчив:

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

Реалізація HostnameVerifier вирішила проблему для HTTPClient 4.5.
digz6666

для тих, хто любить лямбда (JDK1.8), може замінити SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), hostnameVerifierAllowAll);на SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContextBuilder.build(), (hostName, sslSession) -> true);. Він уникає анонімного класу і робить код трохи читабельнішим.
Вієлінько

3

На вершині PoolingHttpClientConnectionManagerразом з Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create().register("https", sslFactory).build(); Якщо ви хочете асинхронне HttpClient використовуючи PoolingNHttpClientConnectionManagerкод shoudl бути схожий на наступне

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

Якщо ви користуєтесь HttpClient 4.5.x, ваш код може бути аналогічним наступному:

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

Не працювали для мене. Я використовую HttpClient: 4.5.5. та HttpCore 4.4.9
Віджай Кумар

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

Довіряйте всім сертифікатам 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());

Це добре працювало з httpclient 4.5.9, просто скопіюйте та вставте весь вміст.
сатья

1

(Я б додав коментар безпосередньо до відповіді васекта, але у мене недостатньо балів репутації (не впевнений у логіці)

У будь-якому випадку ... те, що я хотів сказати, це те, що навіть якщо ви явно не створюєте / просите PoolingConnection, це не означає, що ви його не отримуєте.

Я божеволіла, намагаючись з'ясувати, чому оригінальне рішення не працює для мене, але я проігнорував відповідь васекта, оскільки це "не стосується моєї справи" - неправильно!

Я дивився на свій слід стека, коли низько і ось я побачив посеред нього PoolingConnection. Вибух - я втомив його додаток і успіх !! (наша демонстрація завтра, і я ставав відчайдушним) :-)


0

Ви можете використовувати наступний фрагмент коду для отримання екземпляра HttpClient без перевірки сертифікації 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

Трохи налаштувати відповідь з @divbyzero вище, щоб виправити попередження безпеки сонара

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

Спочатку мені вдалося вимкнути для localhost за допомогою довірчої стратегії, пізніше я додав NoopHostnameVerifier. Тепер він буде працювати як для localhost, так і для будь-якої назви машини

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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.