From a97c3a78d3835c917bcd0f9873e1c196e17ff321 Mon Sep 17 00:00:00 2001 From: John Blum Date: Thu, 19 Mar 2020 13:37:25 -0700 Subject: [PATCH] DATAGEODE-311 - Allow Security configuration applied by Annotations to be used in LocatorApplications. --- .../EmbeddedServiceConfigurationSupport.java | 66 ++++++++---- ...ureLocatorApplicationIntegrationTests.java | 101 ++++++++++++++++++ 2 files changed, 148 insertions(+), 19 deletions(-) create mode 100644 src/test/java/org/springframework/data/gemfire/config/annotation/SecureLocatorApplicationIntegrationTests.java diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java b/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java index 87ef62c7..0b47379c 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/support/EmbeddedServiceConfigurationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright 2020 the original author or authors. + * Copyright 2012-2020 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. @@ -12,6 +12,7 @@ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. + * */ package org.springframework.data.gemfire.config.annotation.support; @@ -35,9 +36,11 @@ import org.springframework.context.annotation.ImportBeanDefinitionRegistrar; import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.gemfire.CacheFactoryBean; +import org.springframework.data.gemfire.LocatorFactoryBean; import org.springframework.data.gemfire.client.ClientCacheFactoryBean; import org.springframework.data.gemfire.config.annotation.AbstractCacheConfiguration; import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer; +import org.springframework.data.gemfire.config.annotation.LocatorConfigurer; import org.springframework.data.gemfire.config.annotation.PeerCacheConfigurer; import org.springframework.data.gemfire.util.CollectionUtils; import org.springframework.util.Assert; @@ -104,7 +107,7 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota } @SuppressWarnings("unused") - protected void registerBeanDefinitions(AnnotationMetadata importingClassMetaData, + protected void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, Map annotationAttributes, BeanDefinitionRegistry registry) { } @@ -133,42 +136,45 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota } protected void registerGemFirePropertiesBeanPostProcessor(BeanDefinitionRegistry registry, - Properties customGemFireProperties) { + Properties gemFireProperties) { - BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(GemFirePropertiesBeanPostProcessor.class); - - builder.addConstructorArgValue(customGemFireProperties); - - BeanDefinitionReaderUtils.registerBeanDefinition(newBeanDefinitionHolder(builder), registry); + registerBeanDefinition(registry, GemFirePropertiesBeanPostProcessor.class, gemFireProperties); } protected void registerGemFirePropertiesConfigurer(BeanDefinitionRegistry registry, Properties gemfireProperties) { registerClientGemFirePropertiesConfigurer(registry, gemfireProperties); + registerLocatorGemFirePropertiesConfigurer(registry, gemfireProperties); registerPeerGemFirePropertiesConfigurer(registry, gemfireProperties); } + private void registerBeanDefinition(BeanDefinitionRegistry registry, Class beanType, + Properties gemfireProperties) { + + BeanDefinitionBuilder builder = + BeanDefinitionBuilder.genericBeanDefinition(beanType); + + builder.addConstructorArgValue(gemfireProperties); + + BeanDefinitionReaderUtils.registerBeanDefinition(newBeanDefinitionHolder(builder), registry); + } + protected void registerClientGemFirePropertiesConfigurer(BeanDefinitionRegistry registry, Properties gemfireProperties) { - BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(ClientGemFirePropertiesConfigurer.class); + registerBeanDefinition(registry, ClientGemFirePropertiesConfigurer.class, gemfireProperties); + } - builder.addConstructorArgValue(gemfireProperties); + protected void registerLocatorGemFirePropertiesConfigurer(BeanDefinitionRegistry registry, + Properties gemfireProperties) { - BeanDefinitionReaderUtils.registerBeanDefinition(newBeanDefinitionHolder(builder), registry); + registerBeanDefinition(registry, LocatorGemFirePropertiesConfigurer.class, gemfireProperties); } protected void registerPeerGemFirePropertiesConfigurer(BeanDefinitionRegistry registry, Properties gemfireProperties) { - BeanDefinitionBuilder builder = - BeanDefinitionBuilder.genericBeanDefinition(PeerGemFirePropertiesConfigurer.class); - - builder.addConstructorArgValue(gemfireProperties); - - BeanDefinitionReaderUtils.registerBeanDefinition(newBeanDefinitionHolder(builder), registry); + registerBeanDefinition(registry, PeerGemFirePropertiesConfigurer.class, gemfireProperties); } protected BeanDefinitionHolder newBeanDefinitionHolder(BeanDefinitionBuilder builder) { @@ -275,6 +281,28 @@ public abstract class EmbeddedServiceConfigurationSupport extends AbstractAnnota } } + protected static class LocatorGemFirePropertiesConfigurer implements LocatorConfigurer { + + private final Properties gemfireProperties; + + public LocatorGemFirePropertiesConfigurer(Properties gemfireProperties) { + + Assert.notEmpty(gemfireProperties, "GemFire Properties are required"); + + this.gemfireProperties = gemfireProperties; + } + + @Override + public void configure(String beanName, LocatorFactoryBean bean) { + + Properties gemfireProperties = bean.getGemFireProperties(); + + gemfireProperties.putAll(this.gemfireProperties); + + bean.setGemFireProperties(gemfireProperties); + } + } + protected static class PeerGemFirePropertiesConfigurer extends AbstractGemFirePropertiesConfigurer implements PeerCacheConfigurer { diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/SecureLocatorApplicationIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/SecureLocatorApplicationIntegrationTests.java new file mode 100644 index 00000000..a729f56d --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/SecureLocatorApplicationIntegrationTests.java @@ -0,0 +1,101 @@ +/* + * Copyright 2020 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. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.data.gemfire.config.annotation; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Properties; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; + +import org.apache.geode.distributed.ConfigurationProperties; +import org.apache.geode.distributed.DistributedSystem; +import org.apache.geode.distributed.Locator; +import org.apache.geode.security.AuthenticationFailedException; +import org.apache.geode.security.ResourcePermission; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; + +/** + * Integration Tests testing the configuration of a "secure" Apache Geode Locator. + * + * @author John Blum + * @see java.util.Properties + * @see org.junit.Test + * @see org.apache.geode.distributed.ConfigurationProperties + * @see org.apache.geode.distributed.Locator + * @see org.apache.geode.distributed.DistributedSystem + * @see org.springframework.data.gemfire.config.annotation.LocatorApplication + * @see org.springframework.data.gemfire.config.annotation.EnableSecurity + * @see org.springframework.test.context.ContextConfiguration + * @see org.springframework.test.context.junit4.SpringRunner + * @since 2.3.0 + */ +@RunWith(SpringRunner.class) +@ContextConfiguration +@SuppressWarnings("unused") +public class SecureLocatorApplicationIntegrationTests { + + @Autowired + private Locator locator; + + @BeforeClass + public static void setup() { + System.setProperty(ApacheShiroSecurityConfiguration.ApacheShiroPresentCondition.SPRING_DATA_GEMFIRE_SECURITY_SHIRO_ENABLED, + Boolean.FALSE.toString()); + } + + @AfterClass + public static void tearDown() { + System.clearProperty(ApacheShiroSecurityConfiguration.ApacheShiroPresentCondition.SPRING_DATA_GEMFIRE_SECURITY_SHIRO_ENABLED); + } + + @Test + public void locatorIsSecure() { + + assertThat(this.locator).isNotNull(); + + DistributedSystem distributedSystem = this.locator.getDistributedSystem(); + + assertThat(distributedSystem).isNotNull(); + assertThat(distributedSystem.getProperties()).isNotNull(); + assertThat(distributedSystem.getProperties().getProperty(ConfigurationProperties.SECURITY_MANAGER)) + .isEqualTo(TestSecurityManager.class.getName()); + } + + @LocatorApplication(port = 0) + //@EnableSecurity(securityManagerClass = TestSecurityManager.class) + @EnableSecurity(securityManagerClassName = "org.springframework.data.gemfire.config.annotation.TestSecurityManager") + static class TestConfiguration { } + + static final class MockSecurityManager implements org.apache.geode.security.SecurityManager { + + @Override + public Object authenticate(Properties credentials) throws AuthenticationFailedException { + throw new AuthenticationFailedException("Identity could not be verified"); + } + + @Override + public boolean authorize(Object principal, ResourcePermission permission) { + return false; + } + } +}