Add auto-configuration support for TLS using SSL when deploying Spring Boot ClientCache applications to PCF using PCC that requires secure Sockets.

The TLS/SSL auto-configuration enables and configures the use of the SSL default context provided by the JRE, which the ClientCache instance uses to obtain the required CERT necessary when creating SSL Sockets between the client and PCC servers.

Resolves gh-61.
This commit is contained in:
John Blum
2019-10-17 15:50:26 -07:00
parent afbbfe9991
commit 25960adc4d
6 changed files with 276 additions and 109 deletions

View File

@@ -62,6 +62,8 @@ import org.springframework.util.StringUtils;
* @see org.springframework.boot.SpringApplication
* @see org.springframework.boot.autoconfigure.AutoConfigureBefore
* @see org.springframework.boot.autoconfigure.EnableAutoConfiguration
* @see org.springframework.boot.autoconfigure.condition.AllNestedConditions
* @see org.springframework.boot.autoconfigure.condition.AnyNestedCondition
* @see org.springframework.boot.autoconfigure.condition.ConditionalOnClass
* @see org.springframework.boot.autoconfigure.condition.ConditionalOnCloudPlatform
* @see org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
@@ -116,6 +118,9 @@ public class ClientSecurityAutoConfiguration {
private static final String SECURITY_PASSWORD_PROPERTY =
AutoConfiguredAuthenticationInitializer.SDG_SECURITY_PASSWORD_PROPERTY;
private static final String SSL_USE_DEFAULT_CONTEXT_PROPERTY =
"spring.data.gemfire.security.ssl.use-default-context";
private static final String VCAP_PROPERTY_SOURCE_NAME = "vcap";
public static class AutoConfiguredCloudSecurityEnvironmentPostProcessor implements EnvironmentPostProcessor {
@@ -212,6 +217,14 @@ public class ClientSecurityAutoConfiguration {
});
}
private void configureSsl(Environment environment, VcapPropertySource vcapPropertySource,
CloudCacheService cloudCacheService, Properties cloudCacheProperties) {
if (cloudCacheService.isTlsEnabled()) {
cloudCacheProperties.setProperty(SSL_USE_DEFAULT_CONTEXT_PROPERTY, Boolean.TRUE.toString());
}
}
public void configureSecurityContext(ConfigurableEnvironment environment) {
String cloudcacheServiceInstanceName = environment.getProperty(CLOUD_CACHE_SERVICE_INSTANCE_NAME_PROPERTY);
@@ -228,6 +241,7 @@ public class ClientSecurityAutoConfiguration {
configureAuthentication(environment, vcapPropertySource, cloudCacheService, cloudCacheProperties);
configureLocators(environment, vcapPropertySource, cloudCacheService, cloudCacheProperties);
configureManagementRestApiAccess(environment, vcapPropertySource, cloudCacheService, cloudCacheProperties);
configureSsl(environment, vcapPropertySource, cloudCacheService, cloudCacheProperties);
environment.getPropertySources()
.addLast(newPropertySource(CLOUD_CACHE_PROPERTY_SOURCE_NAME, cloudCacheProperties));

View File

@@ -235,6 +235,7 @@ public class ClientSecurityAutoConfigurationUnitTests {
assertThat(propertySource.getName()).isEqualTo("boot.data.gemfire.cloudcache");
assertThat(propertySource.getProperty("spring.data.gemfire.security.username")).isEqualTo("Master");
assertThat(propertySource.getProperty("spring.data.gemfire.security.password")).isEqualTo("p@$$w0rd");
assertThat(propertySource.containsProperty("spring.data.gemfire.security.ssl.use-default-context")).isFalse();
assertThat(propertySource.getProperty("spring.data.gemfire.pool.locators"))
.isEqualTo("boombox[10334],skullbox[10334]");
assertThat(propertySource.getProperty("spring.data.gemfire.management.use-http")).isEqualTo("true");
@@ -251,8 +252,6 @@ public class ClientSecurityAutoConfigurationUnitTests {
when(mockEnvironment.containsProperty("spring.data.gemfire.security.username")).thenReturn(true);
when(mockEnvironment.containsProperty("spring.data.gemfire.security.password")).thenReturn(true);
MutablePropertySources propertySources = new MutablePropertySources();
Properties vcapProperties = new Properties();
vcapProperties.setProperty("vcap.application.name", "TestApp");
@@ -269,6 +268,8 @@ public class ClientSecurityAutoConfigurationUnitTests {
PropertySource vcapPropertySource = new PropertiesPropertySource("vcap", vcapProperties);
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(vcapPropertySource);
when(mockEnvironment.getPropertySources()).thenReturn(propertySources);
@@ -288,6 +289,7 @@ public class ClientSecurityAutoConfigurationUnitTests {
assertThat(propertySource.getName()).isEqualTo("boot.data.gemfire.cloudcache");
assertThat(propertySource.containsProperty("spring.data.gemfire.security.username")).isFalse();
assertThat(propertySource.containsProperty("spring.data.gemfire.security.password")).isFalse();
assertThat(propertySource.containsProperty("spring.data.gemfire.security.ssl.use-default-context")).isFalse();
assertThat(propertySource.getProperty("spring.data.gemfire.pool.locators"))
.isEqualTo("boombox[10334],skullbox[10334]");
assertThat(propertySource.containsProperty("spring.data.gemfire.management.use-http")).isFalse();
@@ -296,6 +298,43 @@ public class ClientSecurityAutoConfigurationUnitTests {
assertThat(propertySource.containsProperty("spring.data.gemfire.management.http.port")).isFalse();
}
@Test
public void configuresSecurityContextWithTlsUsingSsl() {
ConfigurableEnvironment mockEnvironment = mock(ConfigurableEnvironment.class);
Properties vcapProperties = new Properties();
vcapProperties.setProperty("vcap.application.name", "TestApp");
vcapProperties.setProperty("vcap.application.uris", "test-app.apps.cloud.skullbox.com");
vcapProperties.setProperty("vcap.services.test-pcc.credentials.tls-enabled", "true");
vcapProperties.setProperty("vcap.services.test-pcc.tags", "junk,gemfire,mock,cloudcache,test");
PropertySource vcapPropertySource = new PropertiesPropertySource("vcap", vcapProperties);
MutablePropertySources propertySources = new MutablePropertySources();
propertySources.addFirst(vcapPropertySource);
when(mockEnvironment.getPropertySources()).thenReturn(propertySources);
AutoConfiguredCloudSecurityEnvironmentPostProcessor environmentPostProcessor =
spy(new AutoConfiguredCloudSecurityEnvironmentPostProcessor());
environmentPostProcessor.configureSecurityContext(mockEnvironment);
verify(mockEnvironment, times(2)).getPropertySources();
assertThat(propertySources.contains("boot.data.gemfire.cloudcache")).isTrue();
PropertySource propertySource = propertySources.get("boot.data.gemfire.cloudcache");
assertThat(propertySource).isNotNull();
assertThat(propertySource.getName()).isEqualTo("boot.data.gemfire.cloudcache");
assertThat(Boolean.parseBoolean(String.valueOf(propertySource
.getProperty("spring.data.gemfire.security.ssl.use-default-context")))).isTrue();
}
@Test
public void configureSecurityContextWhenNoCloudCacheServiceInstanceIsFoundLogsWarning() {