Merge pull request #1138 from orchit/master

* orchit-master:
  Adds ability to disable hostname validation.
This commit is contained in:
Spencer Gibb
2016-06-28 10:33:50 -06:00
3 changed files with 52 additions and 7 deletions

View File

@@ -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(

View File

@@ -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;
}
}

View File

@@ -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;
/**
@@ -54,6 +56,21 @@ public class SimpleHostRoutingFilterTests {
assertEquals(10, connMgr.getDefaultMaxPerRoute());
}
@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();