Java HttpClient with TLS/SSLContext through proxy

1.4k views Asked by At

I want to make a HTTP call to server that uses TLS to authenticate. Moreover server needs my IP to be whitelisted, so with AWS Lambda I need to use proxy. What I want to achieve is HTTP POST request with TLS that goes through proxy.

To achieve TLS protocol I use KeyStore with loaded certs and private key. Making a call without proxy (locally from whitelisted IP) works, so I assume keyStore is configured correctly.

Here is how I build httpClient (it's java.net.http.HttpClient):

var keyManagerFactory = KeyManagerFactory.getInstance("PKIX");
keyManagerFactory.init(keyStore, null);

var trustManagerFactory = TrustManagerFactory.getInstance("PKIX");
trustManagerFactory.init(keyStore, null);

SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), null);

URI proxyUri = config.getProxyUri(); // this is injected object with preloaded config parameters

HttpClient httpClient = HttpClient.newBuilder()
    .sslContext(sslContext)
    .proxy(
      ProxySelector.of(
        InetSocketAddress.createUnresolved(proxyUri.getHost(), proxyUri.getPort())))
    .build();

Now making a request:

String body = createRequestBody(); // creates string with JSON

HttpRequest request = HttpRequest.newBuilder()
    .uri(config.getServiceUri()) // same config as in example above
    .header("Content-Type", "application/json")
    .POST(BodyPublishers.ofString(body))
    .build();

HttpResponse<String> response = httpClient.send(request, BodyHandlers.ofString());

Calling .send(...) causes

java.io.IOException: Tunnel failed, got: 403
# java.net.http/jdk.internal.net.http.HttpClientImpl.send(Unknown Source)
# java.net.http/jdk.internal.net.http.HttpClientFacade.send(Unknown Source)
# (method we are in above example)

Proxy doesn't need any authentication and in other AWS Lambda I've seen this proxy working with builder using only .proxy(...) method just like in the example above. So the only thing that is different is this .sslContext(...).

Do I need some more sslContext configuration? I've been searching for some examples with TLS through proxy, but I've not managed to find anything. HttpClient.Builder Docs doesn't say anything about proxy with sslContext either.

Thanks for help!

1

There are 1 answers

0
Hubert Szymański On BEST ANSWER

As daniel wrote in a comment

It would seem that you have insufficient permission to access the service you're trying to use

It turned out to be proxy config that was blocking traffic to that specific host and port. There is nothing wrong with the code above. After a change in proxy settings to it works as expected.

Thanks for help!