17

I am using Tomcat7, Spring framework for ReST web services. I am trying to call an https web service using Spring RestTemplate. I am getting the following error:

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 check online at stackoverflow. I tried the sample code from the url: Access Https Rest Service using Spring RestTemplate

I couldn't get it to work. Can anybody please tell me based on the code below what do I need to change? Also can anybody tell me or provide me with the pom.xml file which java libraries would I need?

        import org.springframework.web.bind.annotation.RequestMethod;
        import org.springframework.web.client.RestTemplate;

        import com.fasterxml.jackson.core.JsonGenerationException;
        import com.fasterxml.jackson.databind.JsonMappingException;
        import com.fasterxml.jackson.databind.ObjectMapper;
        import com.journaldev.spring.controller.EmpRestURIConstants;
        import com.journaldev.spring.model.CostControlPost;
        import com.journaldev.spring.model.Employee;
        import com.journaldev.spring.model.RfxForUpdate;

        import static org.junit.Assert.*;
        import org.apache.commons.codec.binary.Base64;


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


        public class TestExample2
        {
            public static final String SERVER_LIST="https://abc/sourcing/testServices";


            @Test
            public void testGetListOfServiceNames()
            {
                try
                {


                    RestTemplate restTemplate = new RestTemplate();
                    ResponseEntity<String> response = restTemplate.exchange(SERVER_LIST,HttpMethod.GET,null,String.class);
                    assertNotNull(response);    
                }
                catch(Exception e)
                {
                    System.out.println("e:"+e.getMessage());
                }
            }


        }
pramodc84
  • 1,576
  • 2
  • 25
  • 33
user1272936
  • 299
  • 1
  • 4
  • 15

1 Answers1

31

Either you need to have certificates in your keystore or you can accept all certificates (kind off ignore certificate validation)

So you can re-define bean of rest template as

import javax.net.ssl.SSLContext;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustStrategy;
import java.security.cert.X509Certificate;

@Bean
public RestTemplate restTemplate() throws KeyStoreException, NoSuchAlgorithmException, KeyManagementException {
    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);
    return restTemplate;
 }

You should not need additional jars except for apache core, client and dependencies.

Daniel Benedykt
  • 6,496
  • 12
  • 51
  • 73
user1211
  • 1,507
  • 1
  • 18
  • 27
  • Thank you for responding. I try your code . Where jar files do I need to get for "TrustStragey", "SSLConnectionFactory". and SSLContents? – user1272936 Feb 23 '17 at 17:25
  • These are the imports: javax.net.ssl.SSLContext, org.apache.http.conn.ssl.SSLConnectionSocketFactory, org.apache.http.conn.ssl.TrustStrategy. Just use apache http client – user1211 Feb 23 '17 at 18:13
  • 1
    I followed the manual and add this code, but I faced error: `javax.net.ssl.SSLPeerUnverifiedException: Certificate for <192.168.1.2> doesn't match any of the subject alternative names:[]` – Dariush Jafari Nov 20 '17 at 11:45
  • Hey@Dariush I found another post, https://stackoverflow.com/questions/34655031/javax-net-ssl-sslpeerunverifiedexception-host-name-does-not-match-the-certifica probably I have missed out on something – user1211 Nov 29 '17 at 00:56
  • Bear in mind that this answer will break any other ssl-dependent-client implementation that you might have in your component. – Orkun Mar 13 '18 at 08:37
  • Small correction to above cod, this code will work with below line: SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext,new AllowAllHostnameVerifier()); – Gajendra Kumar Jan 15 '20 at 09:49