允许 Java JDK 11 的不安全 HTTPS 连接 HttpClient
有时需要它来允许不安全的HTTPS连接,例如,在某些应该与任何站点一起使用的网络爬行应用程序中。我在旧的HttpsURLConnection API中使用了一个这样的解决方案,该API最近被JDK 11中新的HttpClient API所取代。使用此新 API 允许不安全的 HTTPS 连接(自签名证书或过期证书)的方法是什么?
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()
但是在发送时,我有例外(使用自签名证书在本地主机上尝试):
java.io.IOException: No name matching localhost found
使用 IP 地址而不是本地主机会给出“不存在使用者替代名称”异常。
在对JDK进行了一些调试后,我发现在抛出异常的地方确实被忽略了,并且使用了一些本地创建的实例。进一步的调试表明,影响主机名验证算法的唯一方法是将系统属性设置为 true。这似乎是一个解决方案。 在上面的代码中没有效果,所以这部分可以被丢弃。让它只能全局配置看起来像是新的HttpClient API中的严重设计缺陷。sslParams
jdk.internal.httpclient.disableHostnameVerification
SSLParameters