Merge branch '2.0.x'

This commit is contained in:
Phillip Webb
2018-09-04 15:15:57 -07:00
5 changed files with 88 additions and 2 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.amqp;
import java.time.Duration;
import java.util.List;
import java.util.Objects;
import com.rabbitmq.client.Channel;
@@ -41,6 +42,7 @@ import org.springframework.boot.context.properties.PropertyMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.util.ReflectionUtils;
/**
* {@link EnableAutoConfiguration Auto-configuration} for {@link RabbitTemplate}.
@@ -91,6 +93,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 properties,
@@ -140,6 +147,13 @@ public class RabbitAutoConfiguration {
map.from(ssl::getTrustStoreType).to(factory::setTrustStoreType);
map.from(ssl::getTrustStore).to(factory::setTrustStore);
map.from(ssl::getTrustStorePassword).to(factory::setTrustStorePassphrase);
map.from(ssl::isValidateServerCertificate).to((validate) -> factory
.setSkipServerCertificateValidation(!validate));
map.from(ssl::getVerifyHostname).when(Objects::nonNull)
.to(factory::setEnableHostnameVerification);
if (ssl.getVerifyHostname() == null && CAN_ENABLE_HOSTNAME_VERIFICATION) {
factory.setEnableHostnameVerification(true);
}
}
map.from(properties::getConnectionTimeout).whenNonNull()
.asInt(Duration::toMillis).to(factory::setConnectionTimeout);

View File

@@ -350,6 +350,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;
}
@@ -414,6 +425,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 {

View File

@@ -19,10 +19,14 @@ package org.springframework.boot.autoconfigure.amqp;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.atomic.AtomicInteger;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import com.rabbitmq.client.Address;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.SslContextFactory;
import com.rabbitmq.client.TrustEverythingTrustManager;
import org.aopalliance.aop.Advice;
import org.junit.Rule;
import org.junit.Test;
@@ -764,6 +768,45 @@ public class RabbitAutoConfigurationTests {
.run((context) -> assertThat(context).hasNotFailed());
}
@Test
public void enableSslWithValidateServerCertificateFalse() throws Exception {
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("spring.rabbitmq.ssl.enabled:true",
"spring.rabbitmq.ssl.validateServerCertificate=false")
.run((context) -> {
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(
context);
TrustManager trustManager = getTrustManager(rabbitConnectionFactory);
assertThat(trustManager)
.isInstanceOf(TrustEverythingTrustManager.class);
});
}
@Test
public void enableSslWithValidateServerCertificateDefault() throws Exception {
this.contextRunner.withUserConfiguration(TestConfiguration.class)
.withPropertyValues("spring.rabbitmq.ssl.enabled:true").run((context) -> {
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory = getTargetConnectionFactory(
context);
TrustManager trustManager = getTrustManager(rabbitConnectionFactory);
assertThat(trustManager)
.isNotInstanceOf(TrustEverythingTrustManager.class);
});
}
private TrustManager getTrustManager(
com.rabbitmq.client.ConnectionFactory rabbitConnectionFactory) {
SslContextFactory sslContextFactory = (SslContextFactory) ReflectionTestUtils
.getField(rabbitConnectionFactory, "sslContextFactory");
SSLContext sslContext = sslContextFactory.create("connection");
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(
AssertableApplicationContext context) {
CachingConnectionFactory connectionFactory = context