1

I am trying to hit an SSL enabled Rest API by disabling the SSL certificate checks as follows;

            TrustManager[] trustAllCerts = new TrustManager[] {new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
            };
            SSLContext sc = SSLContext.getInstance("SSL");
            sc.init(null, trustAllCerts, new java.security.SecureRandom());
            SSLContext.setDefault(sc);
            HostnameVerifier allHostsValid = new HostnameVerifier() {
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            };
            String auth = "<<username>>:<<password>>";
            byte[] authBytes = auth.getBytes(StandardCharsets.UTF_8);
            String encodedAuth = Base64.getEncoder().encodeToString(authBytes);
            String url = "myURLHere";
            Client client = ClientBuilder.newBuilder().sslContext(sc).hostnameVerifier(allHostsValid).build();
            String input = "myJsonHere";
            Response response = client
               .target(url)
               .request()
               .header("Authorization", "Basic " + encodedAuth)
               .post(Entity.json(input));

Refer : https://stackoverflow.com/a/27398820/11226302

However, I am getting the following response;

InboundJaxrsResponse{context=ClientResponse{method=POST, uri=myURLHere, status=502, reason=cannotconnect}}

I also tried the similar logic using HttpsURLConnection.
Refer: https://stackoverflow.com/a/876785/11226302

Getting a similar error as below;

java.lang.RuntimeException: Failed : HTTP error code : 502cannotconnect

I need to do this for testing purposes, but am unable to proceed now.

I am able to get the right response using curl and Postman Client (as mentioned in the Title of this Question) Can anyone suggest what could be going wrong here?

I am using java 8

FYI, the production will have the certificate set up. I am doing this insecure configuration so that I may be able to call this Rest API from my local set up.

Shivam Puri
  • 1,578
  • 12
  • 25
  • Does the URL you are accessing match the contents of its cert? – stark Nov 21 '19 at 12:26
  • I am bypassing the cert check using the above code. Not sure what you mean! – Shivam Puri Nov 21 '19 at 13:16
  • I read that Apache http client configuration silently ignore ClientConfig.sslContext and ClientConfig.hostnameVerifier (Refer https://stackoverflow.com/a/52541638/11226302). Could something similar be happening here somehow? – Shivam Puri Nov 26 '19 at 12:11
  • You want to do this for what testing purposes? Why are you testing an invalid and insecure configuration? – user207421 Nov 29 '19 at 19:50
  • I am testing if the API call does what it is supposed to by calling it from my local machine. But apparently I am unable to call it with this "insecure" configuration. I want help with people here telling me why it is "invalid" and how I can fix it. – Shivam Puri Nov 29 '19 at 19:58
  • 1
    You should not be testing an insecure configuration, except to ensure that it fails. But if you got an HTTP status code, the SSL part of this is working perfectly, if you call trusting anybody and everybody 'perfect'. – user207421 Dec 04 '19 at 08:57
  • @user207421, I do realize the SSL certificate is being passed with my code, but the problem I have is why I am not getting a valid response. Why am I at the same time, getting a valid response if I do a similar thing with curl or Postman client? A thousand other posts across the community suggest they were able to call Rest API's over SSL certified hosts using this method successfully without a certificate, but I am not able to do so. Hence I've posted the question in the first place! – Shivam Puri Dec 04 '19 at 09:03
  • Agree with @user207421. Yuo have recived a 502 "Bad Gateway" https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502. So you have successfully connected via SSL to something, and then that something is complaining that it cannot forward the connection to an onward target. The something is probably a local network proxy - try adding the targetted host to your proxy exceptions list? – Richard Woods Dec 06 '19 at 03:51

1 Answers1

2

A 502 error indicates that you were able to connect successfully to a TLS protected endpoint (possibly by ignoring its untrustworthy certificate). What has gone wrong is that this endpoint is failing to proxy the connection to another host, and it is the proxy that "cannot connect".

https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/502

It follows that you must be suffering from a configuration issue specific to your java process that does not affect curl or postman. An example i've seen would be where you are attempting to access a webservices endpoint on localhost in windows, but due to OS and office LAN settings the connection is sent to the networks' internet proxy first - which doesn't know what to do with the address '127.0.0.1'. I'd check your OS network settings are set appropriatly, and that the environment variables that can be used to override them in a java process are not set:

https.proxyHost
https.proxyPort
http.nonProxyHosts

Local programs like Fiddler might also be attempting to act as a proxy and contributing to the issue.

Another possibility is that your counterparty is using a reverse proxy at their end, which is struggling to route the request issued by the java process for some reason. Make sure you are using exactly the same hostname with the java client as you used with curl/postman (not a manually resolved IP address or local DNS alias).

An aside: hacking in a no-op trustmanager while prototyping is something many Java developers will have done at one point or another - but it is a much better practise to add the certificate you wish to trust to your local JVM truststore, or a process specific truststore instead. That way you don't have to use different code in testing and production.

https://docs.oracle.com/cd/E79792_01/resa/pdf/141/html/merch_sg/apps-chapter%207.htm#CHDJBIJD

Richard Woods
  • 2,163
  • 5
  • 18