Disable SSL certificate validation in RestTemplate

Carvia Tech | December 05, 2019 | 3 min read | 451 views


In non production environments, we often need to ignore bad ssl certificates (self-signed, expired, non trusted root, etc) for testing purpose. We will configure RestTemplate to still connect to these hosts without failing.

RestTemplate can give any of the below error if SSL certificate of the target host is not valid:

PKIX path building failed: sun.security.provider.certpath
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
javax.net.ssl.SSLHandshakeException: PKIX path building failed

Reasons for invalid certificate could be:

  • Expired certificate

  • Self-signed certificate

  • Wrong host information in certificate

  • Revoked certificate

  • Untrusted root of certificate

Gradle setup

We will be using Spring Boot 2 environment for this article, but you are free to choose any other compatible version of Spring.

build.gradle
plugins {
    id 'org.springframework.boot' version '2.2.1.RELEASE'
    id 'java'
}

apply plugin: 'io.spring.dependency-management'

group = 'com.shunya.tutorial'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.apache.httpcomponents:httpclient:4.5.10'

    testImplementation('org.springframework.boot:spring-boot-starter-test') {
        exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
    }
}

We have added Apache HttpClient dependency to our project because that is required for customization of RestTemplate.

Creating RestTemplate Bean

We will use RestTemplateBuilder to create a custom RestTemplate Bean that will trust all kind of bad SSL certificates. Please be aware that this should never be done for any production environment.

RestTemplate Bean that trust all SSL certificates and does not verify hostname
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) throws NoSuchAlgorithmException, KeyManagementException {

        TrustManager[] trustAllCerts = new TrustManager[] {
                new X509TrustManager() {
                    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                        return new X509Certificate[0];
                    }
                    public void checkClientTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                    public void checkServerTrusted(
                            java.security.cert.X509Certificate[] certs, String authType) {
                    }
                }
        };  (1)
        SSLContext sslContext = SSLContext.getInstance("SSL");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); (2)
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLContext(sslContext)
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .build();   (3)
        HttpComponentsClientHttpRequestFactory customRequestFactory = new HttpComponentsClientHttpRequestFactory();
        customRequestFactory.setHttpClient(httpClient);
        return builder.requestFactory(() -> customRequestFactory).build();  (4)
    }
}
1 Creating trust manager that blindly trusts all kind of SSL certificates (good ones as well as bad ones)
2 Install trust manager to SSL Context
3 Create an HttpClient that uses the custom SSLContext and do not verify cert hostname
4 Create a RestTemplate that uses custom request factory

If we do not want to use RestTemplateBuilder, then we can simply create a new instance of RestTemplate and pass it the customRequestFactory Object, as shown below:

...
class customRequestFactory = new HttpComponentsClientHttpRequestFactory();
        customRequestFactory.setHttpClient(httpClient);
return new RestTemplate(customRequestFactory);

Now we can autowire this RestTemplate Bean anywhere we want to use.

A simple startup runner can be used to test the RestTemplate’s behaviour

Application runner that makes Http request to bad SSL url
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

@Component
public class StartupRunner implements ApplicationRunner {

    @Autowired
    private RestTemplate restTemplate;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        final ResponseEntity<String> responseEntity = restTemplate.getForEntity("https://self-signed.badssl.com/", String.class);
        if(responseEntity.getStatusCode().is2xxSuccessful()) {
            System.out.println(responseEntity.getBody());
        }
    }
}

This shall not throw any error this time.

Reference


Top articles in this category:
  1. Self Signed Certificate in Spring 5 WebClient
  2. RestTemplate with Basic Authentication
  3. Send Gupshup SMS using Java API
  4. File Upload in Spring MVC using RestTemplate with ByteArrayResource & FileSystemResource
  5. How does Session handling works in Servlet environment
  6. Spring Boot file upload with Kotlin and Junit 5
  7. Custom banner in spring boot


Find more on this topic:
Spring Framework image
Spring Framework

Spring Framework - MVC, Dependency Injection, Spring Hibernate, Spring Data JPA, Spring Boot and Spring Cloud for Microservices Architecture.

Last updated 1 week ago


Recommended books for interview preparation:

This website uses cookies to ensure you get the best experience on our website. more info