1

I have googled it with issue. But those are not able to solve my problem.I have an issue with the SSL certificate in my code while calling a rest control.

My control method is:

@CrossOrigin(origins = "http://localhost:4200")
@RequestMapping(value = "/token", method = RequestMethod.POST, produces = "application/json")
public @ResponseBody TokenModel GetToken(@RequestBody RequestBodyJson requestBodyJson) {
    TokenModel response = null; 
    RestTemplate restTemplate = new RestTemplate();
    try {                          
        response = new GenericRestClient<RequestBodyJson, TokenModel>().execute(
            new RequestDetails(url, HttpMethod.POST), requestBodyJson, responseHandler,TokenModel.class);
        restTemplate.getForEntity(url , TokenModel.class);
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
    return response;
}

Error is:-I/O error on POST request for "https://myurl.com": 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

can anyone can help me here?

M Hamza Javed
  • 1,269
  • 4
  • 17
  • 31
Pranav MS
  • 2,235
  • 2
  • 23
  • 50
  • Rest is usually supposed to work on https, but you are using http, that might be the problem i.e "https :// localhost:4200" – Aurangzeb Apr 08 '19 at 09:08
  • localhost:4200 is my frontend. So i am calling my microservice from UI. And from MS i'm trying to call another api `HTTPS://WWW.myurl.com` then only im getting the issue. – Pranav MS Apr 08 '19 at 09:11
  • 1
    The reason why the SSL certificate of https///myurl.com is not trusted by java can be that the CA certificate is not imported in cacerts your application is using.For some details you can refer to the followin question: [How do I find out what keystore my JVM is using?](https://stackoverflow.com/questions/8980364/how-do-i-find-out-what-keystore-my-jvm-is-using) – da-sha1 Apr 08 '19 at 09:17
  • Get the certificate `https///myurl.com` is using and import it to the `cacerts` of your JVM. –  Apr 08 '19 at 09:26
  • @EugenCovaci can you please give some reference for the same? – Pranav MS Apr 08 '19 at 09:32
  • See @da-sha1 comment. –  Apr 08 '19 at 09:40
  • To get the SSL certificate `https///myurl.com` is using you can either do it via your Browser (view SSL certificate and then download it) or if you are on linux, download it using `openssl` – da-sha1 Apr 08 '19 at 09:43
  • thanks friends for your help – Pranav MS Apr 08 '19 at 09:54

1 Answers1

2

Thanks guys for your help.

I have solved the problem by

In my POM.XML i have added one dependency

<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5</version>
</dependency>

Then my JAVA code is

@RequestMapping(value = "/gettokens", method = RequestMethod.POST, produces = "application/json")
public @ResponseBody ResponseEntity<TokenModel> GetTokens(@RequestBody RequestBodyJson requestBodyJson)
        throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
    ResponseEntity<TokenModel> response = null;
    TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
    SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
            .loadTrustMaterial(null, acceptingTrustStrategy).build();
    SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
    CloseableHttpClient httpClient = HttpClients.custom()
            .setSSLSocketFactory(csf).build();
    HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory();
    requestFactory.setHttpClient(httpClient);
    RestTemplate restTemplate = new RestTemplate(requestFactory);       
    try {                          
        MultiValueMap<String, String> headers = new LinkedMultiValueMap<String, String>();
        Map map = new HashMap<String, String>();
        map.put("Content-Type", "application/json");
        headers.setAll(map);
        HttpEntity<?> _HttpEntityRequestBodyJson = new HttpEntity<>(requestBodyJson, headers); 
        response= restTemplate.exchange(url, HttpMethod.POST,_HttpEntityRequestBodyJson, new ParameterizedTypeReference<TokenModel>() {});  
        System.out.println(response.getBody());
    } catch (Exception e) {
        System.out.println(e.getMessage());
    }
    return response;
}
M Hamza Javed
  • 1,269
  • 4
  • 17
  • 31
Pranav MS
  • 2,235
  • 2
  • 23
  • 50
  • Please be careful, you are overriding the standard handling of certificates , i.e. your are configuring your application to **always** trust the remote SSL certificate without verifying it. – da-sha1 Apr 08 '19 at 10:01
  • For more info please refer to [Resolving javax.net.ssl.SSLHandshakeException](https://stackoverflow.com/questions/9619030/resolving-javax-net-ssl-sslhandshakeexception-sun-security-validator-validatore) – da-sha1 Apr 08 '19 at 10:17
  • for the testing purpose – Pranav MS Apr 08 '19 at 11:11