1
votes

I have to send GET request to some API without any parameters so I wrote the code:

public Boolean getData(String apiUrl) {

        try {
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.getForEntity(apiUrl, String.class);

            if (responseEntity.getStatusCode().toString().equals("200")) {
                theLogger.info("Server successfully answered with response code: {} - {}", responseEntity.getStatusCode().toString(), responseEntity.getBody());
                return true;
            } else {
                theLogger.error("Something goes wrong! Server answered with response code: {} and error: {}", responseEntity.getStatusCode().toString(), responseEntity.getBody());
                return false;
            }

        } catch (Exception theException) {
            theException.printStackTrace();
            theLogger.error("Cannot send channelInfo! Exception: " + theException);
            return false;
        }

}

It works when API url is HTTP, but doesn't work with HTTPS. It says:

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I believe it's because my code doesn't trust this certificate. But I don't know what should I do with it? The API is public and it opens in any web-browser it is just some https site. I couldn't believe that I should download certificates for all https sites which I work with and add this certificates somewhere. I believe that it should be the more common way to trust this public sites.

1

1 Answers

0
votes

I found the answer here So if have to deal with certificate which was issued by not trusted CA, but in your case, you don't really care about trust. You can disable SSL certificate validation by code:

import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

public class SSLCertificateValidation {

    public static void disable() {
        try {
            SSLContext sslc = SSLContext.getInstance("TLS");
            TrustManager[] trustManagerArray = { new NullX509TrustManager() };
            sslc.init(null, trustManagerArray, null);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslc.getSocketFactory());
            HttpsURLConnection.setDefaultHostnameVerifier(new NullHostnameVerifier());
        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    private static class NullX509TrustManager implements X509TrustManager {
        public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            System.out.println();
        }
        public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            System.out.println();
        }
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }
    }

    private static class NullHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
    }

}

Invoke SSLCertificateValidation.disable() prior to making a HTTPS call.