From 6fc39d0095dc2cfbf2f361403854cba2c1d16656 Mon Sep 17 00:00:00 2001 From: John Blum Date: Sat, 11 Nov 2017 16:13:37 -0800 Subject: [PATCH] DATAGEODE-55 - Adapt to Apache Geode Integrated Security Framework changes. --- .../ApacheShiroSecurityConfiguration.java | 81 +++++-------------- .../config/annotation/EnableSecurity.java | 7 +- .../GeodeIntegratedSecurityConfiguration.java | 3 +- ...AbstractGeodeSecurityIntegrationTests.java | 9 ++- ...urityManagerSecurityIntegrationTests.java} | 4 +- ...acheShiroIniSecurityIntegrationTests.java} | 2 +- ...heShiroRealmSecurityIntegrationTests.java} | 5 +- 7 files changed, 41 insertions(+), 70 deletions(-) rename src/test/java/org/springframework/data/gemfire/config/annotation/{ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests.java => ApacheGeodeSecurityManagerSecurityIntegrationTests.java} (96%) rename src/test/java/org/springframework/data/gemfire/config/annotation/{ApacheShiroIniGeodeSecurityIntegrationTests.java => ApacheShiroIniSecurityIntegrationTests.java} (94%) rename src/test/java/org/springframework/data/gemfire/config/annotation/{ApacheShiroRealmGeodeSecurityIntegrationTests.java => ApacheShiroRealmSecurityIntegrationTests.java} (95%) diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/ApacheShiroSecurityConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/ApacheShiroSecurityConfiguration.java index 9c34855a..f9be4871 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/ApacheShiroSecurityConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/ApacheShiroSecurityConfiguration.java @@ -18,9 +18,8 @@ package org.springframework.data.gemfire.config.annotation; import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; -import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException; -import java.lang.reflect.Field; +import java.lang.annotation.Annotation; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -28,7 +27,6 @@ import java.util.Map; import java.util.Optional; import org.apache.geode.cache.GemFireCache; -import org.apache.geode.internal.security.SecurityService; import org.apache.shiro.SecurityUtils; import org.apache.shiro.mgt.DefaultSecurityManager; import org.apache.shiro.realm.Realm; @@ -36,6 +34,7 @@ import org.apache.shiro.spring.LifecycleBeanPostProcessor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.ListableBeanFactory; +import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Condition; @@ -44,13 +43,12 @@ import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.OrderComparator; import org.springframework.core.type.AnnotatedTypeMetadata; -import org.springframework.data.gemfire.GemfireUtils; import org.springframework.data.gemfire.config.annotation.support.AbstractAnnotationConfigSupport; import org.springframework.data.gemfire.util.CollectionUtils; +import org.springframework.data.gemfire.util.SpringUtils; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.ObjectUtils; -import org.springframework.util.ReflectionUtils; /** * The {@link ApacheShiroSecurityConfiguration} class is a Spring {@link Configuration @Configuration} component @@ -86,7 +84,7 @@ public class ApacheShiroSecurityConfiguration extends AbstractAnnotationConfigSu * @see org.springframework.data.gemfire.config.annotation.EnableSecurity */ @Override - protected Class getAnnotationType() { + protected Class getAnnotationType() { return EnableSecurity.class; } @@ -120,6 +118,14 @@ public class ApacheShiroSecurityConfiguration extends AbstractAnnotationConfigSu return (ListableBeanFactory) getBeanFactory(); } + @Bean + public BeanFactoryPostProcessor shiroGemFireBeanFactoryPostProcessor() { + + return configurableListableBeanFactory -> + SpringUtils.addDependsOn(configurableListableBeanFactory.getBeanDefinition("gemfireCache"), + "shiroSecurityManager"); + } + /** * {@link Bean} definition to define, configure and register an Apache Shiro Spring * {@link LifecycleBeanPostProcessor} to automatically call lifecycle callback methods @@ -157,29 +163,16 @@ public class ApacheShiroSecurityConfiguration extends AbstractAnnotationConfigSu * with the Apache Shiro security framework but Apache Geode security could not be enabled. * @see org.apache.shiro.mgt.SecurityManager * @see #registerSecurityManager(org.apache.shiro.mgt.SecurityManager) - * @see #enableApacheGeodeSecurity() * @see #resolveRealms() - * @see #registerSecurityManager(org.apache.shiro.mgt.SecurityManager) - * @see #enableApacheGeodeSecurity() */ @Bean - public org.apache.shiro.mgt.SecurityManager shiroSecurityManager(GemFireCache gemfireCache) { + public org.apache.shiro.mgt.SecurityManager shiroSecurityManager() { - org.apache.shiro.mgt.SecurityManager shiroSecurityManager = null; - - List realms = resolveRealms(); - - if (!realms.isEmpty()) { - - shiroSecurityManager = registerSecurityManager(new DefaultSecurityManager(realms)); - - if (!enableApacheGeodeSecurity()) { - throw newIllegalStateException("Failed to enable security services in %s", - GemfireUtils.apacheGeodeProductName()); - } - } - - return shiroSecurityManager; + return Optional.ofNullable(resolveRealms()) + .filter(realms -> !realms.isEmpty()) + .map(realms -> new DefaultSecurityManager(realms)) + .map(this::registerSecurityManager) + .orElse(null); } /** @@ -198,7 +191,9 @@ public class ApacheShiroSecurityConfiguration extends AbstractAnnotationConfigSu protected List resolveRealms() { try { - Map realmBeans = getListableBeanFactory().getBeansOfType(Realm.class, false, true); + + Map realmBeans = getListableBeanFactory().getBeansOfType(Realm.class, + false, false); List realms = new ArrayList<>(CollectionUtils.nullSafeMap(realmBeans).values()); @@ -231,40 +226,6 @@ public class ApacheShiroSecurityConfiguration extends AbstractAnnotationConfigSu return securityManager; } - /** - * Sets the Apache Geode, Integrated Security {@link SecurityService} property {@literal isIntegratedSecurity} - * to {@literal true} to indicate that Apache Geode security is enabled. - * - * @return a boolean value indicating whether Apache Geode's Integrated Security framework services - * were successfully enabled. - * @see org.apache.geode.internal.security.SecurityService#getSecurityService() - */ - protected boolean enableApacheGeodeSecurity() { - - SecurityService securityService = SecurityService.getSecurityService(); - - if (securityService != null) { - - String isIntegratedSecurityFieldName = "isIntegratedSecurity"; - - Field isIntegratedSecurity = ReflectionUtils.findField(securityService.getClass(), - isIntegratedSecurityFieldName, Boolean.class); - - isIntegratedSecurity = Optional.ofNullable(isIntegratedSecurity).orElseGet(() -> - ReflectionUtils.findField(securityService.getClass(), isIntegratedSecurityFieldName, Boolean.TYPE)); - - if (isIntegratedSecurity != null) { - - ReflectionUtils.makeAccessible(isIntegratedSecurity); - ReflectionUtils.setField(isIntegratedSecurity, securityService, Boolean.TRUE); - - return true; - } - } - - return false; - } - /** * A Spring {@link Condition} to determine whether the user has included (declared) the 'shiro-spring' dependency * on their application's classpath, which is necessary for configuring Apache Shiro to secure Apache Geode diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSecurity.java b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSecurity.java index 7cefeb20..13f3e519 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSecurity.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/EnableSecurity.java @@ -47,8 +47,11 @@ import org.springframework.context.annotation.Import; @Retention(RetentionPolicy.RUNTIME) @Inherited @Documented -@Import({ ApacheShiroSecurityConfiguration.class, AutoConfiguredAuthenticationConfiguration.class, - GeodeIntegratedSecurityConfiguration.class }) +@Import({ + ApacheShiroSecurityConfiguration.class, + AutoConfiguredAuthenticationConfiguration.class, + GeodeIntegratedSecurityConfiguration.class +}) @UsesGemFireProperties @SuppressWarnings({ "unused" }) public @interface EnableSecurity { diff --git a/src/main/java/org/springframework/data/gemfire/config/annotation/GeodeIntegratedSecurityConfiguration.java b/src/main/java/org/springframework/data/gemfire/config/annotation/GeodeIntegratedSecurityConfiguration.java index 3968f1ee..c404e923 100644 --- a/src/main/java/org/springframework/data/gemfire/config/annotation/GeodeIntegratedSecurityConfiguration.java +++ b/src/main/java/org/springframework/data/gemfire/config/annotation/GeodeIntegratedSecurityConfiguration.java @@ -17,6 +17,7 @@ package org.springframework.data.gemfire.config.annotation; +import java.lang.annotation.Annotation; import java.util.Map; import java.util.Properties; @@ -47,7 +48,7 @@ public class GeodeIntegratedSecurityConfiguration extends EmbeddedServiceConfigu * @see org.springframework.data.gemfire.config.annotation.EnableSecurity */ @Override - protected Class getAnnotationType() { + protected Class getAnnotationType() { return EnableSecurity.class; } diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/AbstractGeodeSecurityIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/AbstractGeodeSecurityIntegrationTests.java index 15ad4902..ef1fcada 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/AbstractGeodeSecurityIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/AbstractGeodeSecurityIntegrationTests.java @@ -141,6 +141,7 @@ public abstract class AbstractGeodeSecurityIntegrationTests extends ClientServer @Test @DirtiesContext public void authorizedUser() { + assertThat(echo.get("one")).isEqualTo("one"); assertThat(echo.put("two", "four")).isNull(); assertThat(echo.get("two")).isEqualTo("four"); @@ -148,11 +149,13 @@ public abstract class AbstractGeodeSecurityIntegrationTests extends ClientServer @Test(expected = NotAuthorizedException.class) public void unauthorizedUser() { + try { assertThat(echo.get("one")).isEqualTo("one"); echo.put("two", "four"); } catch (ServerOperationException expected) { + assertThat(expected).hasMessageContaining("analyst not authorized for DATA:WRITE:Echo:two"); assertThat(expected).hasCauseInstanceOf(NotAuthorizedException.class); @@ -233,9 +236,9 @@ public abstract class AbstractGeodeSecurityIntegrationTests extends ClientServer @CacheServerApplication(name = "GeodeSecurityIntegrationTestsServer", logLevel = TEST_GEMFIRE_LOG_LEVEL, port = CACHE_SERVER_PORT) @Import({ - ApacheShiroIniGeodeSecurityIntegrationTests.ApacheShiroIniConfiguration.class, - ApacheShiroRealmGeodeSecurityIntegrationTests.ApacheShiroRealmConfiguration.class, - ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests.ApacheGeodeSecurityManagerConfiguration.class + ApacheShiroIniSecurityIntegrationTests.ApacheShiroIniConfiguration.class, + ApacheShiroRealmSecurityIntegrationTests.ApacheShiroRealmConfiguration.class, + ApacheGeodeSecurityManagerSecurityIntegrationTests.ApacheGeodeSecurityManagerConfiguration.class }) @Profile("apache-geode-server") public static class GeodeServerConfiguration { diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheGeodeSecurityManagerSecurityIntegrationTests.java similarity index 96% rename from src/test/java/org/springframework/data/gemfire/config/annotation/ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests.java rename to src/test/java/org/springframework/data/gemfire/config/annotation/ApacheGeodeSecurityManagerSecurityIntegrationTests.java index 10a9e215..0a890705 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheGeodeSecurityManagerSecurityIntegrationTests.java @@ -47,7 +47,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @ContextConfiguration(classes = AbstractGeodeSecurityIntegrationTests.GeodeClientConfiguration.class) @ActiveProfiles("apache-geode-client") -public class ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests extends AbstractGeodeSecurityIntegrationTests { +public class ApacheGeodeSecurityManagerSecurityIntegrationTests extends AbstractGeodeSecurityIntegrationTests { protected static final String GEODE_SECURITY_MANAGER_PROPERTY_CONFIGURATION_PROFILE = "geode-security-manager-property-configuration"; @@ -59,7 +59,7 @@ public class ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests extends Abs @Configuration @EnableSecurity(securityManagerClassName = - "org.springframework.data.gemfire.config.annotation.ApacheGeodeSecurityManagerGeodeSecurityIntegrationTests$TestGeodeSecurityManager") + "org.springframework.data.gemfire.config.annotation.ApacheGeodeSecurityManagerSecurityIntegrationTests$TestGeodeSecurityManager") @Profile(GEODE_SECURITY_MANAGER_PROPERTY_CONFIGURATION_PROFILE) public static class ApacheGeodeSecurityManagerConfiguration { } diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroIniGeodeSecurityIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroIniSecurityIntegrationTests.java similarity index 94% rename from src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroIniGeodeSecurityIntegrationTests.java rename to src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroIniSecurityIntegrationTests.java index e196de15..22bb0759 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroIniGeodeSecurityIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroIniSecurityIntegrationTests.java @@ -37,7 +37,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @ContextConfiguration(classes = AbstractGeodeSecurityIntegrationTests.GeodeClientConfiguration.class) @ActiveProfiles("apache-geode-client") -public class ApacheShiroIniGeodeSecurityIntegrationTests extends AbstractGeodeSecurityIntegrationTests { +public class ApacheShiroIniSecurityIntegrationTests extends AbstractGeodeSecurityIntegrationTests { protected static final String SHIRO_INI_CONFIGURATION_PROFILE = "shiro-ini-configuration"; diff --git a/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroRealmGeodeSecurityIntegrationTests.java b/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroRealmSecurityIntegrationTests.java similarity index 95% rename from src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroRealmGeodeSecurityIntegrationTests.java rename to src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroRealmSecurityIntegrationTests.java index bf667395..048bf5b1 100644 --- a/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroRealmGeodeSecurityIntegrationTests.java +++ b/src/test/java/org/springframework/data/gemfire/config/annotation/ApacheShiroRealmSecurityIntegrationTests.java @@ -41,7 +41,7 @@ import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @ContextConfiguration(classes = AbstractGeodeSecurityIntegrationTests.GeodeClientConfiguration.class) @ActiveProfiles("apache-geode-client") -public class ApacheShiroRealmGeodeSecurityIntegrationTests extends AbstractGeodeSecurityIntegrationTests { +public class ApacheShiroRealmSecurityIntegrationTests extends AbstractGeodeSecurityIntegrationTests { protected static final String SHIRO_REALM_CONFIGURATION_PROFILE = "shiro-realm-configuration"; @@ -58,9 +58,12 @@ public class ApacheShiroRealmGeodeSecurityIntegrationTests extends AbstractGeode @Bean public PropertiesRealm shiroRealm() { + PropertiesRealm propertiesRealm = new PropertiesRealm(); + propertiesRealm.setResourcePath("classpath:shiro.properties"); propertiesRealm.setPermissionResolver(new GeodePermissionResolver()); + return propertiesRealm; } }