diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java
index 20823f29c4..c44cec3f21 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfiguration.java
@@ -39,6 +39,7 @@ import org.springframework.context.annotation.Import;
import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
+import org.springframework.util.ReflectionUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link RabbitTemplate}.
@@ -87,6 +88,11 @@ public class RabbitAutoConfiguration {
@ConditionalOnMissingBean(ConnectionFactory.class)
protected static class RabbitConnectionFactoryCreator {
+ // Only available in rabbitmq-java-client 5.4.0 +
+ private static final boolean CAN_ENABLE_HOSTNAME_VERIFICATION = ReflectionUtils
+ .findMethod(com.rabbitmq.client.ConnectionFactory.class,
+ "enableHostnameVerification") != null;
+
@Bean
public CachingConnectionFactory rabbitConnectionFactory(RabbitProperties config)
throws Exception {
@@ -117,6 +123,16 @@ public class RabbitAutoConfiguration {
factory.setKeyStorePassphrase(ssl.getKeyStorePassword());
factory.setTrustStore(ssl.getTrustStore());
factory.setTrustStorePassphrase(ssl.getTrustStorePassword());
+ factory.setSkipServerCertificateValidation(
+ !ssl.isValidateServerCertificate());
+ if (ssl.getVerifyHostname() != null) {
+ factory.setEnableHostnameVerification(ssl.getVerifyHostname());
+ }
+ else {
+ if (CAN_ENABLE_HOSTNAME_VERIFICATION) {
+ factory.setEnableHostnameVerification(true);
+ }
+ }
}
if (config.getConnectionTimeout() != null) {
factory.setConnectionTimeout(config.getConnectionTimeout());
diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java
index e78387f2e5..e18c9d65b0 100644
--- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java
+++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/amqp/RabbitProperties.java
@@ -337,6 +337,17 @@ public class RabbitProperties {
*/
private String algorithm;
+ /**
+ * Whether to enable server side certificate validation.
+ */
+ private boolean validateServerCertificate = true;
+
+ /**
+ * Whether to enable hostname verification. Requires AMQP client 4.8 or above and
+ * defaults to true when a suitable client version is used.
+ */
+ private Boolean verifyHostname;
+
public boolean isEnabled() {
return this.enabled;
}
@@ -385,6 +396,22 @@ public class RabbitProperties {
this.algorithm = sslAlgorithm;
}
+ public boolean isValidateServerCertificate() {
+ return this.validateServerCertificate;
+ }
+
+ public void setValidateServerCertificate(boolean validateServerCertificate) {
+ this.validateServerCertificate = validateServerCertificate;
+ }
+
+ public Boolean getVerifyHostname() {
+ return this.verifyHostname;
+ }
+
+ public void setVerifyHostname(Boolean verifyHostname) {
+ this.verifyHostname = verifyHostname;
+ }
+
}
public static class Cache {
diff --git a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java
index 7c03a568b6..9866f52caf 100644
--- a/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java
+++ b/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/amqp/RabbitAutoConfigurationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2017 the original author or authors.
+ * Copyright 2012-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,8 +18,10 @@ package org.springframework.boot.autoconfigure.amqp;
import javax.net.SocketFactory;
import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
import com.rabbitmq.client.Address;
+import com.rabbitmq.client.NullTrustManager;
import org.aopalliance.aop.Advice;
import org.junit.After;
import org.junit.Rule;
@@ -53,6 +55,7 @@ import org.springframework.retry.backoff.ExponentialBackOffPolicy;
import org.springframework.retry.interceptor.MethodInvocationRecoverer;
import org.springframework.retry.policy.SimpleRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
+import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
@@ -411,6 +414,8 @@ public class RabbitAutoConfigurationTests {
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory();
assertThat(rabbitConnectionFactory.getSocketFactory())
.as("SocketFactory must use SSL").isInstanceOf(SSLSocketFactory.class);
+ TrustManager trustManager = getTrustManager(rabbitConnectionFactory);
+ assertThat(trustManager).isNotInstanceOf(NullTrustManager.class);
}
@Test
@@ -422,7 +427,38 @@ public class RabbitAutoConfigurationTests {
"spring.rabbitmq.ssl.keyStore=foo",
"spring.rabbitmq.ssl.keyStorePassword=secret",
"spring.rabbitmq.ssl.trustStore=bar",
- "spring.rabbitmq.ssl.trustStorePassword=secret");
+ "spring.rabbitmq.ssl.trustStorePassword=secret",
+ "spring.rabbitmq.ssl.validateServerCertificate=false");
+ getTargetConnectionFactory();
+ }
+
+ @Test
+ public void enableSslWithValidateServerCertificateFalse() throws Exception {
+ load(TestConfiguration.class, "spring.rabbitmq.ssl.enabled:true",
+ "spring.rabbitmq.ssl.validateServerCertificate=false");
+ com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory();
+ TrustManager trustManager = getTrustManager(rabbitConnectionFactory);
+ assertThat(trustManager).isInstanceOf(NullTrustManager.class);
+ }
+
+ @Test
+ public void enableSslWithValidateServerCertificateDefault() throws Exception {
+ load(TestConfiguration.class, "spring.rabbitmq.ssl.enabled:true");
+ com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory();
+ TrustManager trustManager = getTrustManager(rabbitConnectionFactory);
+ assertThat(trustManager).isNotInstanceOf(NullTrustManager.class);
+ }
+
+ private TrustManager getTrustManager(
+ com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory) {
+ Object sslContext = ReflectionTestUtils.getField(rabbitConnectionFactory,
+ "sslContext");
+ Object spi = ReflectionTestUtils.getField(sslContext, "contextSpi");
+ Object trustManager = ReflectionTestUtils.getField(spi, "trustManager");
+ while (trustManager.getClass().getName().endsWith("Wrapper")) {
+ trustManager = ReflectionTestUtils.getField(trustManager, "tm");
+ }
+ return (TrustManager) trustManager;
}
private com.rabbitmq.client.ConnectionFactory getTargetConnectionFactory() {
diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml
index 98d125c859..6a10e69df8 100644
--- a/spring-boot-dependencies/pom.xml
+++ b/spring-boot-dependencies/pom.xml
@@ -140,6 +140,7 @@
2.1.6
9.4.1212.jre7
4.1.4
+ 4.0.3
2.0.8.RELEASE
2.0.7.RELEASE
2.53.1
@@ -152,7 +153,7 @@
5.5.5
1.0-groovy-2.4
4.3.18.RELEASE
- 1.7.9.RELEASE
+ 1.7.10.BUILD-SNAPSHOT
1.2.6.RELEASE
3.0.9.RELEASE
Ingalls-SR14
@@ -730,6 +731,11 @@
+
+ com.rabbitmq
+ amqp-client
+ ${rabbit-amqp-client.version}
+
com.samskivert
jmustache
@@ -3263,4 +3269,4 @@
integration-test
-
\ No newline at end of file
+
diff --git a/spring-boot-samples/spring-boot-sample-amqp/pom.xml b/spring-boot-samples/spring-boot-sample-amqp/pom.xml
index 94c200de2b..3b6d1ba42f 100644
--- a/spring-boot-samples/spring-boot-sample-amqp/pom.xml
+++ b/spring-boot-samples/spring-boot-sample-amqp/pom.xml
@@ -1,5 +1,7 @@
-
+
4.0.0
@@ -17,6 +19,7 @@
${basedir}/../..
+ 4.8.0