Любое из вышеуказанных решений будет работать для самозаверяющего сертификата. Третий вариант - в случае, когда сервер предоставляет действительный, неподписанный сертификат, но для хоста, который не совпадает ни с одним из имен в сертификате, который он предоставляет, тогда системное свойство "jdk.internal.httpclient.disableHostnameVerification" может быть установлено в "true", и это заставит сертификат быть принятым так же, как API HostnameVerifier использовался ранее. Обратите внимание, что в обычных развертываниях не ожидается использование какого-либо из этих механизмов, поскольку должна быть возможность автоматической проверки сертификата, предоставленного любым правильно настроенным сервером HTTPS.

а необходимо разрешить небезопасные соединения HTTPS, например, в некоторых веб-приложениях, которые должны работать с любым сайтом. я использовалодно такое решение со старым HttpsURLConnection API, который недавно был замененновый HttpClient API в JDK 11. Как разрешить небезопасные соединения HTTPS (самозаверяющий или устаревший сертификат) с этим новым API?

UPD: код, который я пробовал (в Kotlin, но отображается непосредственно на Java):

    val trustAllCerts = arrayOf<TrustManager>(object: X509TrustManager {
        override fun getAcceptedIssuers(): Array<X509Certificate>? = null
        override fun checkClientTrusted(certs: Array<X509Certificate>, authType: String) {}
        override fun checkServerTrusted(certs: Array<X509Certificate>, authType: String) {}
    })

    val sslContext = SSLContext.getInstance("SSL")
    sslContext.init(null, trustAllCerts, SecureRandom())

    val sslParams = SSLParameters()
    // This should prevent host validation
    sslParams.endpointIdentificationAlgorithm = ""

    httpClient = HttpClient.newBuilder()
        .sslContext(sslContext)
        .sslParameters(sslParams)
        .build()

Но при отправке у меня есть исключение (при попытке на localhost с самозаверяющим сертификатом):

java.io.IOException: No name matching localhost found

Использование IP-адреса вместо localhost дает исключение «Отсутствуют альтернативные имена субъектов».

После некоторой отладки JDK я обнаружил, чтоsslParams действительно игнорируются в том месте, где выдается исключение, и используется какой-то локально созданный экземпляр. Дальнейшая отладка показала, что единственным способом повлиять на алгоритм проверки имени хоста является настройкаjdk.internal.httpclient.disableHostnameVerification системное свойство к истине. И это, кажется, решение.SSLParameters в приведенном выше коде не имеют никакого эффекта, поэтому эту часть можно отбросить. Возможность настройки только в глобальном масштабе выглядит как серьезный недостаток дизайна в новом HttpClient API.

Ответы на вопрос(2)

Ваш ответ на вопрос