java jdk https,允许Java JDK 11 HttpClient的不安全的HTTPS连接

Sometimes it is needed to allow insecure HTTPS connections, e.g. in some web-crawling applications which should work with any site. I used one such solution with old HttpsURLConnection API which was recently superseded by the new HttpClient API in JDK 11. What is the way to allow insecure HTTPS connections (self-signed or expired certificate) with this new API?

UPD: The code I tried (in Kotlin but maps directly to Java):

val trustAllCerts = arrayOf(object: X509TrustManager {

override fun getAcceptedIssuers(): Array? = null

override fun checkClientTrusted(certs: Array, authType: String) {}

override fun checkServerTrusted(certs: Array, 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()

But on sending I have exception (trying on localhost with self-signed certificate):

java.io.IOException: No name matching localhost found

Using IP address instead of localhost gives "No subject alternative names present" exception.

After some debugging of JDK I found that sslParams are really ignored in the place the exception is thrown and some locally created instance is used. Further debugging revealed that the only way to affect the hostname verification algorithm is setting jdk.internal.httpclient.disableHostnameVerification system property to true. And that's seems to be a solution. SSLParameters in the code above have no effect so this part can be discarded. Making it configurable only globally looks like serious design flaw in new HttpClient API.

解决方案

With Java 11, as well you can do a similar effort as mentioned in the selected answer in the link shared with the HttpClient built as:

HttpClient httpClient = HttpClient.newBuilder()

.connectTimeout(Duration.ofMillis( * 1000))

.sslContext(sc) // SSL context 'sc' initialised as earlier

.sslParameters(parameters) // ssl parameters if overriden

.build();

with a sample request

HttpRequest requestBuilder = HttpRequest.newBuilder()

.uri(URI.create("https://www.example.com/getSomething"))

.GET()

.build();

can be executed as:

httpClient.send(requestBuilder, HttpResponse.BodyHandlers.ofString()); // sends the request

Update from comments, to disable the hostname verification, currently one can use the system property:

-Djdk.internal.httpclient.disableHostnameVerification

which can be set programmatically as following :-

final Properties props = System.getProperties();

props.setProperty("jdk.internal.httpclient.disableHostnameVerification", Boolean.TRUE.toString());

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值