Kong / unirest-java

Unirest in Java: Simplified, lightweight HTTP client library.
http://kong.github.io/unirest-java/
MIT License
2.61k stars 593 forks source link

Add support for SSL/TLS with SSLContext #314

Closed Hakky54 closed 4 years ago

Hakky54 commented 4 years ago

Hi, first thank you first for this great library.

Is your feature request related to a problem? Please describe. I want to make a couple of https requests for different scenario's which is a bit hard with the current possibilities. The main setup what I prefer is to separate the client's certificate and list of trusted certificate in two different keystores. Loading two keystore is currently not possible. The only available ssl configuration are these two:

public Config clientCertificateStore(KeyStore store, String password) {...}

public Config clientCertificateStore(String fileLocation, String password) {...}

So this is unfortunately not possible with these methods. And if I call these methods with different keystores it will override keystore field within the configuration of unirest.

Describe the solution you'd like A possible solution would supporting SSLContext from javax which could be something like this:

public Config sslContext(javax.net.ssl.SSLContext sslContext) {...}

With this option you will enable the consumer of the library to provide any kind of ssl/tls stategy. Like one way tls, two way tls, trusting signed certificates, trusting unsigned certificates or enforcing a specific tls protocol version like TLS v1.3

Would be cool if this could be a new feature request

ryber commented 4 years ago

sure, I will note that, as Apache is the underlying engine of Unirest, I'm a little constrained to what it can do, and also the fact that this part of Apache is pretty hard to navigate. However it does look like it supports javax.net.ssl.SSLContext, so I will take a look

Hakky54 commented 4 years ago

I have tried another configuration and it works, so I am not sure if that would the solution for Unirest.

What I currently do is the following as a workaround:

SSLContext sslContext = SSLContext.getInstance("TLSv1.3");
sslContext.init(keyManagers, trustManagers, null);

HttpClient httpClient = HttpClients.custom()
    .setSSLContext(sslContext)
    .setSSLHostnameVerifier(new DefaultHostnameVerifier())
    .build();

Unirest.primaryInstance()
    .config()
    .httpClient(config -> ApacheClient.builder(httpClient).apply(config));
ryber commented 4 years ago

Turns out this was a lot easier than I thought. We were already building a SSLContext internally so allowing a user to just pass in their own is pretty simple.

I would like to get some test validation however and currently the Custom Cert on badssl.com is expired. Let's give them a few days to get it updated. (link in the pull request https://github.com/Kong/unirest-java/pull/316)

Hakky54 commented 4 years ago

Thank you, it is a nice to have feature :) Glad to hear it was easy for you to implement.

ryber commented 4 years ago

this is released in 3.2.00