Unverified Commit 723287b3 by Patrick Cornelißen Committed by Spencer Gibb

Adds ability to disable hostname validation.

Adds property zuul.sslHostnameValidationEnabled to be able to disable the hostname validation in the simpleHostRoutingFilter fixes gh-1057
parent 46b2e45f
......@@ -111,7 +111,7 @@ public class ZuulProperties {
private boolean traceRequestBody = true;
/**
* Flag to say that path elelents past the first semicolon can be dropped.
* Flag to say that path elements past the first semicolon can be dropped.
*/
private boolean removeSemicolonContent = true;
......@@ -125,6 +125,12 @@ public class ZuulProperties {
private Set<String> sensitiveHeaders = new LinkedHashSet<>(
Arrays.asList("Cookie", "Set-Cookie", "Authorization"));
/**
* Flag to say whether the hostname for ssl connections should be verified or now. Default is true.
* This should only be used in test setups!
*/
private boolean sslHostnameValidationEnabled =true;
public Set<String> getIgnoredHeaders() {
Set<String> ignoredHeaders = new LinkedHashSet<>(this.ignoredHeaders);
if (ClassUtils.isPresent(
......
......@@ -53,11 +53,13 @@ import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.InputStreamEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicHeader;
......@@ -66,7 +68,6 @@ import org.apache.http.protocol.HttpContext;
import org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties.Host;
import org.springframework.http.HttpStatus;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
......@@ -94,6 +95,8 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
private final Timer connectionManagerTimer = new Timer(
"SimpleHostRoutingFilter.connectionManagerTimer", true);
private boolean sslHostnameValidationEnabled;
private ProxyRequestHelper helper;
private Host hostProperties;
private PoolingHttpClientConnectionManager connectionManager;
......@@ -115,6 +118,7 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
public SimpleHostRoutingFilter(ProxyRequestHelper helper, ZuulProperties properties) {
this.helper = helper;
this.hostProperties = properties.getHost();
this.sslHostnameValidationEnabled = properties.isSslHostnameValidationEnabled();
}
@PostConstruct
......@@ -204,11 +208,18 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
}
} }, new SecureRandom());
final Registry<ConnectionSocketFactory> registry = RegistryBuilder
RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder
.<ConnectionSocketFactory> create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", new SSLConnectionSocketFactory(sslContext))
.build();
.register("http", PlainConnectionSocketFactory.INSTANCE);
if (sslHostnameValidationEnabled) {
registryBuilder.register("https",
new SSLConnectionSocketFactory(sslContext));
}
else {
registryBuilder.register("https", new SSLConnectionSocketFactory(
sslContext, NoopHostnameVerifier.INSTANCE));
}
final Registry<ConnectionSocketFactory> registry = registryBuilder.build();
this.connectionManager = new PoolingHttpClientConnectionManager(registry);
this.connectionManager
......@@ -228,7 +239,11 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
.setConnectTimeout(CONNECTION_TIMEOUT.get())
.setCookieSpec(CookieSpecs.IGNORE_COOKIES).build();
return HttpClients.custom().setConnectionManager(newConnectionManager())
HttpClientBuilder httpClientBuilder = HttpClients.custom();
if (!sslHostnameValidationEnabled) {
httpClientBuilder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
}
return httpClientBuilder.setConnectionManager(newConnectionManager())
.setDefaultRequestConfig(requestConfig)
.setRetryHandler(new DefaultHttpRequestRetryHandler(0, false))
.setRedirectStrategy(new RedirectStrategy() {
......@@ -363,4 +378,11 @@ public class SimpleHostRoutingFilter extends ZuulFilter {
this.helper.addIgnoredHeaders(names);
}
/**
* Determines whether the filter enables the validation for ssl hostnames.
* @return
*/
boolean isSslHostnameValidationEnabled() {
return sslHostnameValidationEnabled;
}
}
......@@ -28,6 +28,8 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.springframework.boot.test.EnvironmentTestUtils.addEnvironment;
/**
......@@ -55,6 +57,21 @@ public class SimpleHostRoutingFilterTests {
}
@Test
public void validateSslHostnamesByDefault() {
setupContext();
assertTrue("Hostname verification should be enabled by default",
getFilter().isSslHostnameValidationEnabled());
}
@Test
public void validationOfSslHostnamesCanBeDisabledViaProperty() {
addEnvironment(this.context, "zuul.sslHostnameValidationEnabled=false");
setupContext();
assertFalse("Hostname verification should be disabled via property",
getFilter().isSslHostnameValidationEnabled());
}
@Test
public void defaultPropertiesAreApplied() {
setupContext();
PoolingHttpClientConnectionManager connMgr = getFilter().newConnectionManager();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment