This is an automated email from the ASF dual-hosted git repository. jinmeiliao pushed a commit to branch expireAuthentication in repository https://gitbox.apache.org/repos/asf/geode.git
commit 8507bed1c7b182791c50eb5b96029d0f6a29b9d9 Author: Joris Melchior <[email protected]> AuthorDate: Fri Aug 20 12:43:30 2021 -0400 GEODE-9460: Add testing for mutli-user scenarios (#6755) Co-Authored-By Jinmei Liao <[email protected]> --- .../geode/security/AuthExpirationDUnitTest.java | 72 ++++++++++++++++++++-- .../geode/security/ExpirableSecurityManager.java | 19 +++++- .../security/UpdatableUserAuthInitialize.java | 1 + 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/geode-core/src/upgradeTest/java/org/apache/geode/security/AuthExpirationDUnitTest.java b/geode-core/src/upgradeTest/java/org/apache/geode/security/AuthExpirationDUnitTest.java index 117cc77..0aae286 100644 --- a/geode-core/src/upgradeTest/java/org/apache/geode/security/AuthExpirationDUnitTest.java +++ b/geode-core/src/upgradeTest/java/org/apache/geode/security/AuthExpirationDUnitTest.java @@ -15,12 +15,14 @@ package org.apache.geode.security; import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_CLIENT_AUTH_INIT; -import static org.apache.geode.distributed.ConfigurationProperties.SECURITY_MANAGER; import static org.apache.geode.test.version.VersionManager.CURRENT_VERSION; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; import java.util.Arrays; import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Properties; import org.junit.After; import org.junit.Rule; @@ -31,6 +33,7 @@ import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.apache.geode.cache.Region; +import org.apache.geode.cache.RegionService; import org.apache.geode.cache.RegionShortcut; import org.apache.geode.cache.client.ClientCache; import org.apache.geode.cache.client.ClientRegionFactory; @@ -45,6 +48,8 @@ import org.apache.geode.test.junit.runners.CategoryWithParameterizedRunnerFactor @RunWith(Parameterized.class) @Parameterized.UseParametersRunnerFactory(CategoryWithParameterizedRunnerFactory.class) public class AuthExpirationDUnitTest { + static RegionService regionService0; + static RegionService regionService1; @Parameterized.Parameter public String clientVersion; @@ -58,13 +63,12 @@ public class AuthExpirationDUnitTest { @Rule public ClusterStartupRule lsRule = new ClusterStartupRule(); - @Rule public RestoreSystemProperties restore = new RestoreSystemProperties(); @Rule public ServerStarterRule server = new ServerStarterRule() - .withProperty(SECURITY_MANAGER, ExpirableSecurityManager.class.getName()) + .withSecurityManager(ExpirableSecurityManager.class) .withRegion(RegionShortcut.REPLICATE, "region"); @After @@ -85,9 +89,10 @@ public class AuthExpirationDUnitTest { clientVM.invoke(() -> { ClientCache clientCache = ClusterStartupRule.getClientCache(); UpdatableUserAuthInitialize.setUser("user1"); - ClientRegionFactory clientRegionFactory = + assert clientCache != null; + ClientRegionFactory<Object, Object> clientRegionFactory = clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY); - Region region = clientRegionFactory.create("region"); + Region<Object, Object> region = clientRegionFactory.create("region"); region.put(0, "value0"); }); @@ -98,7 +103,8 @@ public class AuthExpirationDUnitTest { clientVM.invoke(() -> { UpdatableUserAuthInitialize.setUser("user2"); ClientCache clientCache = ClusterStartupRule.getClientCache(); - Region region = clientCache.getRegion("region"); + assert clientCache != null; + Region<Object, Object> region = clientCache.getRegion("region"); region.put(1, "value1"); }); @@ -109,4 +115,58 @@ public class AuthExpirationDUnitTest { assertThat(region.size()).isEqualTo(2); } + @Test + public void userShouldReAuthenticateWhenCredentialExpiredAndOperationSucceed() throws Exception { + int serverPort = server.getPort(); + ClientVM clientVM = lsRule.startClientVM(0, clientVersion, + c -> c.withMultiUser(true) + .withProperty(SECURITY_CLIENT_AUTH_INIT, UpdatableUserAuthInitialize.class.getName()) + .withPoolSubscription(true) + .withServerConnection(serverPort)); + + clientVM.invoke(() -> { + UpdatableUserAuthInitialize.setUser("serviceUser0"); + ClientCache clientCache = ClusterStartupRule.getClientCache(); + assert clientCache != null; + clientCache.createClientRegionFactory(ClientRegionShortcut.PROXY).create("region"); + Properties userSecurityProperties = new Properties(); + userSecurityProperties.put(SECURITY_CLIENT_AUTH_INIT, + UpdatableUserAuthInitialize.class.getName()); + regionService0 = clientCache.createAuthenticatedView(userSecurityProperties); + Region<Object, Object> region = regionService0.getRegion("/region"); + region.put(0, "value0"); + + UpdatableUserAuthInitialize.setUser("serviceUser1"); + userSecurityProperties.put(SECURITY_CLIENT_AUTH_INIT, + UpdatableUserAuthInitialize.class.getName()); + regionService1 = clientCache.createAuthenticatedView(userSecurityProperties); + region = regionService1.getRegion("/region"); + region.put(1, "value1"); + }); + + ExpirableSecurityManager.addExpiredUser("serviceUser1"); + + clientVM.invoke(() -> { + Region<Object, Object> region = regionService1.getRegion("/region"); + UpdatableUserAuthInitialize.setUser("serviceUser2"); + region.put(2, "value2"); + + region = regionService0.getRegion("/region"); + region.put(3, "value3"); + regionService0.close(); + regionService1.close(); + }); + + Region<Object, Object> region = server.getCache().getRegion("/region"); + assertThat(ExpirableSecurityManager.getExpiredUsers().size()).isEqualTo(1); + assertThat(ExpirableSecurityManager.getExpiredUsers().contains("serviceUser1")).isTrue(); + Map<Object, List<ResourcePermission>> authorizedOps = + ExpirableSecurityManager.getAuthorizedOps(); + assertThat(authorizedOps.size()).isEqualTo(3); + assertThat(authorizedOps.get("serviceUser0").size()).isEqualTo(2); + assertThat(authorizedOps.get("serviceUser1").size()).isEqualTo(1); + assertThat(authorizedOps.get("serviceUser2").size()).isEqualTo(1); + assertThat(region.size()).isEqualTo(4); + } + } diff --git a/geode-junit/src/main/java/org/apache/geode/security/ExpirableSecurityManager.java b/geode-junit/src/main/java/org/apache/geode/security/ExpirableSecurityManager.java index fc1021d..5c4d177 100644 --- a/geode-junit/src/main/java/org/apache/geode/security/ExpirableSecurityManager.java +++ b/geode-junit/src/main/java/org/apache/geode/security/ExpirableSecurityManager.java @@ -15,6 +15,9 @@ package org.apache.geode.security; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -32,12 +35,21 @@ public class ExpirableSecurityManager extends SimpleSecurityManager { // use static field for ease of testing since there is only one instance of this in each VM // we only need ConcurrentHashSet here, but map is only construct available in the library private static final Set<String> EXPIRED_USERS = ConcurrentHashMap.newKeySet(); + private static final Map<Object, List<ResourcePermission>> AUTHORIZED_OPS = + new ConcurrentHashMap<>(); @Override public boolean authorize(Object principal, ResourcePermission permission) { - if (EXPIRED_USERS.contains(principal)) { + if (EXPIRED_USERS.contains((String) principal)) { throw new AuthenticationExpiredException("User authentication expired."); } + List<ResourcePermission> permissions = AUTHORIZED_OPS.get(principal); + if (permissions == null) { + permissions = new ArrayList<>(); + } + permissions.add(permission); + AUTHORIZED_OPS.put(principal, permissions); + // always authorized return true; } @@ -50,7 +62,12 @@ public class ExpirableSecurityManager extends SimpleSecurityManager { return EXPIRED_USERS; } + public static Map<Object, List<ResourcePermission>> getAuthorizedOps() { + return AUTHORIZED_OPS; + } + public static void reset() { EXPIRED_USERS.clear(); + AUTHORIZED_OPS.clear(); } } diff --git a/geode-junit/src/main/java/org/apache/geode/security/UpdatableUserAuthInitialize.java b/geode-junit/src/main/java/org/apache/geode/security/UpdatableUserAuthInitialize.java index 0a0e6b4..2b1a0b1 100644 --- a/geode-junit/src/main/java/org/apache/geode/security/UpdatableUserAuthInitialize.java +++ b/geode-junit/src/main/java/org/apache/geode/security/UpdatableUserAuthInitialize.java @@ -37,6 +37,7 @@ public class UpdatableUserAuthInitialize implements AuthInitialize { Properties credentials = new Properties(); credentials.put("security-username", user.get()); credentials.put("security-password", user.get()); + return credentials; }
