Skip to content

Commit

Permalink
Relaxed SSL validation with RestTemplate interceptors (#1869)
Browse files Browse the repository at this point in the history
* Relaxed SSL validation with RestTemplate interceptors

* Formatting

* Checkstyle

fixes #1868
  • Loading branch information
nkolosnjaji authored Mar 21, 2023
1 parent 05b3ee7 commit 5343cb9
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@

package org.springframework.cloud.contract.wiremock;

import java.lang.reflect.Field;

import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.impl.classic.HttpClients;
import org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager;
Expand All @@ -29,13 +31,17 @@
import org.springframework.boot.web.client.RestTemplateCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.client.RestTemplate;

import static org.apache.hc.client5.http.ssl.NoopHostnameVerifier.INSTANCE;

/**
* @author Dave Syer
* @author Nikola Kološnjaji
*
*/
@Configuration(proxyBeanMethods = false)
Expand All @@ -48,11 +54,20 @@ public RestTemplateCustomizer wiremockRestTemplateCustomizer() {
return new RestTemplateCustomizer() {
@Override
public void customize(RestTemplate restTemplate) {
if (restTemplate.getRequestFactory() instanceof HttpComponentsClientHttpRequestFactory) {
HttpComponentsClientHttpRequestFactory factory = (HttpComponentsClientHttpRequestFactory) restTemplate
.getRequestFactory();
if (restTemplate.getRequestFactory() instanceof HttpComponentsClientHttpRequestFactory factory) {
factory.setHttpClient(createSslHttpClient());
}
else if (restTemplate.getRequestFactory() instanceof InterceptingClientHttpRequestFactory) {
Field requestFactoryField = ReflectionUtils.findField(RestTemplate.class, "requestFactory");
if (requestFactoryField != null) {
requestFactoryField.setAccessible(true);
ClientHttpRequestFactory requestFactory = (ClientHttpRequestFactory) ReflectionUtils
.getField(requestFactoryField, restTemplate);
if (requestFactory instanceof HttpComponentsClientHttpRequestFactory factory) {
factory.setHttpClient(createSslHttpClient());
}
}
}
}

private HttpClient createSslHttpClient() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.core.api.Assertions.assertThat;

/**
* @author Dave Syer
* @author Nikola Kološnjaji
*
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = WiremockTestsApplication.class,
properties = "app.baseUrl=https://localhost:${wiremock.server.https-port}",
Expand All @@ -50,6 +55,20 @@ public void contextLoads() throws Exception {
assertThat(this.service.go()).isEqualTo("Hello World!");
}

@Test
public void contextLoadsWithApacheClient() throws Exception {
stubFor(get(urlEqualTo("/test"))
.willReturn(aResponse().withHeader("Content-Type", "text/plain").withBody("Hello World!")));
assertThat(this.service.goWithApacheClient()).isEqualTo("Hello World!");
}

@Test
public void contextLoadsWithApacheClientAndAdditonalInterceptor() throws Exception {
stubFor(get(urlEqualTo("/test"))
.willReturn(aResponse().withHeader("Content-Type", "text/plain").withBody("Hello World!")));
assertThat(this.service.goWithApacheClientAndAdditonalInterceptor()).isEqualTo("Hello World!");
}

@Test
public void portsAreFixed() {
boolean httpPortDynamic = this.wireMockProperties.getServer().isPortDynamic();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,47 +22,51 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.RequestEntity;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

/**
* @author Dave Syer
* @author Nikola Kološnjaji
*
*/
@Configuration
@EnableAutoConfiguration
@Import({ Service.class, Controller.class })
@Import(Service.class)
public class WiremockTestsApplication {

public static void main(String[] args) {
SpringApplication.run(WiremockTestsApplication.class, args);
}

@Bean
@Primary
public RestTemplate restTemplate() {
return new RestTemplate();
}

}

@RestController
class Controller {

private final Service service;

Controller(Service service) {
this.service = service;
@Bean
public RestTemplate apacheHttpClient(RestTemplateBuilder builder) {
return builder.requestFactory(() -> new HttpComponentsClientHttpRequestFactory()).build();
}

@RequestMapping("/")
public String home() {
return this.service.go();
@Bean
public RestTemplate apacheHttpClientWithInterceptor(RestTemplateBuilder builder) {
return builder.requestFactory(() -> new HttpComponentsClientHttpRequestFactory())
.additionalInterceptors(new BasicAuthenticationInterceptor("u", "p")).build();
}

}
Expand All @@ -77,8 +81,15 @@ class Service {

private RestTemplate restTemplate;

Service(RestTemplate restTemplate) {
private RestTemplate apacheHttpClient;

private RestTemplate apacheHttpClientWithInterceptor;

Service(RestTemplate restTemplate, @Qualifier("apacheHttpClient") RestTemplate apacheHttpClient,
@Qualifier("apacheHttpClientWithInterceptor") RestTemplate apacheHttpClientWithInterceptor) {
this.restTemplate = restTemplate;
this.apacheHttpClient = apacheHttpClient;
this.apacheHttpClientWithInterceptor = apacheHttpClientWithInterceptor;
}

public String go() {
Expand All @@ -87,6 +98,18 @@ public String go() {
return this.restTemplate.getForEntity(requestUrl, String.class).getBody();
}

public String goWithApacheClient() {
String requestUrl = this.base + "/test";
log.info("Will send a request to [" + requestUrl + "]");
return this.apacheHttpClient.getForEntity(requestUrl, String.class).getBody();
}

public String goWithApacheClientAndAdditonalInterceptor() {
String requestUrl = this.base + "/test";
log.info("Will send a request to [" + requestUrl + "]");
return this.apacheHttpClientWithInterceptor.getForEntity(requestUrl, String.class).getBody();
}

public String link() {
String requestUrl = this.base + "/link";
log.info("Will send a request to [" + requestUrl + "]");
Expand Down

0 comments on commit 5343cb9

Please sign in to comment.