Repository: incubator-geode Updated Branches: refs/heads/develop 5f8405495 -> 774044eeb
Geode-1569: require principal to be Serializable so that post process can happen in a remote server Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/774044ee Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/774044ee Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/774044ee Branch: refs/heads/develop Commit: 774044eeb6a5f1ce4456afda19f1b6b12c9e0cc4 Parents: 5f84054 Author: Jinmei Liao <jil...@pivotal.io> Authored: Thu Aug 4 16:15:33 2016 -0700 Committer: Jinmei Liao <jil...@pivotal.io> Committed: Mon Aug 8 08:26:14 2016 -0700 ---------------------------------------------------------------------- .../internal/security/GeodeSecurityUtil.java | 24 ++-- .../security/IntegratedSecurityService.java | 6 +- .../internal/security/SecurityService.java | 6 +- .../security/shiro/CustomAuthRealm.java | 6 +- .../internal/cli/commands/DataCommands.java | 8 +- .../internal/cli/domain/DataCommandRequest.java | 10 ++ .../cli/functions/DataCommandFunction.java | 20 ++- .../apache/geode/security/PostProcessor.java | 7 +- .../apache/geode/security/SecurityManager.java | 8 +- .../security/templates/SamplePostProcessor.java | 12 +- .../templates/SampleSecurityManager.java | 12 +- .../security/AbstractSecureServerDUnitTest.java | 16 +-- .../security/NoShowValue1PostProcessor.java | 4 +- .../PDXGfshPostProcessorOnRemoteServerTest.java | 142 +++++++++++++++++++ .../gemfire/security/PDXPostProcessor.java | 6 +- .../gemfire/security/SpySecurityManager.java | 4 +- 16 files changed, 237 insertions(+), 54 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java index a9c2162..f73790b 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtil.java @@ -19,19 +19,19 @@ package com.gemstone.gemfire.internal.security; import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; import java.io.IOException; +import java.io.Serializable; import java.lang.reflect.Method; import java.security.AccessController; -import java.security.Principal; import java.util.Properties; import java.util.Set; import java.util.concurrent.Callable; import org.apache.commons.lang.SerializationException; import org.apache.commons.lang.StringUtils; +import org.apache.geode.security.PostProcessor; import org.apache.geode.security.ResourcePermission; import org.apache.geode.security.ResourcePermission.Operation; import org.apache.geode.security.ResourcePermission.Resource; -import org.apache.geode.security.PostProcessor; import org.apache.geode.security.SecurityManager; import org.apache.logging.log4j.Logger; import org.apache.shiro.SecurityUtils; @@ -366,14 +366,20 @@ public class GeodeSecurityUtil { } public static Object postProcess(String regionPath, Object key, Object value, boolean valueIsSerialized){ - if(!needPostProcess()) - return value; - - Subject subject = getSubject(); + return postProcess(null, regionPath, key, value, valueIsSerialized); + } - if(subject == null) + public static Object postProcess(Serializable principal, String regionPath, Object key, Object value, boolean valueIsSerialized) { + if (!needPostProcess()) return value; + if (principal == null) { + Subject subject = getSubject(); + if (subject == null) + return value; + principal = (Serializable) subject.getPrincipal(); + } + String regionName = StringUtils.stripStart(regionPath, "/"); Object newValue = null; @@ -382,14 +388,14 @@ public class GeodeSecurityUtil { if (valueIsSerialized && value instanceof byte[]) { try { Object oldObj = EntryEventImpl.deserialize((byte[]) value); - Object newObj = postProcessor.processRegionValue((Principal)subject.getPrincipal(), regionName, key, oldObj); + Object newObj = postProcessor.processRegionValue(principal, regionName, key, oldObj); newValue = BlobHelper.serializeToBlob(newObj); } catch (IOException|SerializationException e) { throw new GemFireIOException("Exception de/serializing entry value", e); } } else { - newValue = postProcessor.processRegionValue((Principal) subject.getPrincipal(), regionName, key, value); + newValue = postProcessor.processRegionValue(principal, regionName, key, value); } return newValue; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java index 84a0c32..30da9bf 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/IntegratedSecurityService.java @@ -19,7 +19,6 @@ package com.gemstone.gemfire.internal.security; import java.io.InvalidObjectException; import java.io.ObjectInputStream; import java.io.Serializable; -import java.util.List; import java.util.Properties; import java.util.concurrent.Callable; @@ -171,6 +170,11 @@ public class IntegratedSecurityService implements SecurityService, Serializable } @Override + public Object postProcess(final Serializable principal, final String regionPath, final Object key, final Object value, final boolean valueIsSerialized) { + return GeodeSecurityUtil.postProcess(principal, regionPath, key, value, valueIsSerialized); + } + + @Override public boolean isClientSecurityRequired() { return GeodeSecurityUtil.isClientSecurityRequired(); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java index 9629ba3..b562892 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/SecurityService.java @@ -16,16 +16,17 @@ */ package com.gemstone.gemfire.internal.security; +import java.io.Serializable; import java.util.Properties; import java.util.concurrent.Callable; -import com.gemstone.gemfire.management.internal.security.ResourceOperation; - import org.apache.geode.security.ResourcePermission; import org.apache.geode.security.SecurityManager; import org.apache.shiro.subject.Subject; import org.apache.shiro.util.ThreadState; +import com.gemstone.gemfire.management.internal.security.ResourceOperation; + public interface SecurityService { ThreadState bindSubject(Subject subject); @@ -52,6 +53,7 @@ public interface SecurityService { void close(); boolean needPostProcess(); Object postProcess(String regionPath, Object key, Object value, boolean valueIsSerialized); + Object postProcess(Serializable principal, String regionPath, Object key, Object value, boolean valueIsSerialized); boolean isClientSecurityRequired(); boolean isPeerSecurityRequired(); boolean isIntegratedSecurity(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java index edb0790..b9dd8c0 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/CustomAuthRealm.java @@ -16,7 +16,7 @@ */ package com.gemstone.gemfire.internal.security.shiro; -import java.security.Principal; +import java.io.Serializable; import java.util.Properties; import org.apache.geode.security.ResourcePermission; @@ -71,7 +71,7 @@ public class CustomAuthRealm extends AuthorizingRealm { credentialProps.put(ResourceConstants.USER_NAME, username); credentialProps.put(ResourceConstants.PASSWORD, password); - Principal principal = securityManager.authenticate(credentialProps); + Serializable principal = securityManager.authenticate(credentialProps); try { return new SimpleAuthenticationInfo(principal, authToken.getPassword(), REALM_NAME); @@ -89,7 +89,7 @@ public class CustomAuthRealm extends AuthorizingRealm { @Override public boolean isPermitted(PrincipalCollection principals, Permission permission) { ResourcePermission context = (ResourcePermission) permission; - Principal principal = (Principal) principals.getPrimaryPrincipal(); + Serializable principal = (Serializable)principals.getPrimaryPrincipal(); return securityManager.authorize(principal, context); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java index ae87b72..d6ff853 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/commands/DataCommands.java @@ -16,6 +16,7 @@ */ package com.gemstone.gemfire.management.internal.cli.commands; +import java.io.Serializable; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; @@ -32,6 +33,7 @@ import java.util.concurrent.TimeoutException; import org.apache.geode.security.ResourcePermission.Operation; import org.apache.geode.security.ResourcePermission.Resource; +import org.apache.shiro.subject.Subject; import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliAvailabilityIndicator; import org.springframework.shell.core.annotation.CliCommand; @@ -1060,6 +1062,10 @@ public class DataCommands implements CommandMarker { request.setRegionName(regionPath); request.setValueClass(valueClass); request.setLoadOnCacheMiss(loadOnCacheMiss); + Subject subject = this.securityService.getSubject(); + if(subject!=null){ + request.setPrincipal((Serializable)subject.getPrincipal()); + } dataResult = callFunctionForRegion(request, getfn, memberList); } else dataResult = DataCommandResult.createGetInfoResult(key, null, null, @@ -1067,7 +1073,7 @@ public class DataCommands implements CommandMarker { CliStrings.GET__MSG__REGION_NOT_FOUND_ON_ALL_MEMBERS, regionPath), false); } else { - dataResult = getfn.get(key, keyClass, valueClass, regionPath, loadOnCacheMiss); + dataResult = getfn.get(null, key, keyClass, valueClass, regionPath, loadOnCacheMiss); } dataResult.setKeyClass(keyClass); if (valueClass != null) http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java index 92d4579..76582c3 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/domain/DataCommandRequest.java @@ -46,6 +46,7 @@ public class DataCommandRequest implements /*Data*/ Serializable{ private String removeAllKeys; private String value; private String valueClass; + private Serializable principal; public static final String NEW_LINE = System.getProperty("line.separator"); @@ -135,6 +136,9 @@ public class DataCommandRequest implements /*Data*/ Serializable{ public boolean isLoadOnCacheMiss() { return loadOnCacheMiss; } + public Serializable getPrincipal() { + return principal; + } public void setKey(String key) { this.key = key; @@ -180,6 +184,10 @@ public class DataCommandRequest implements /*Data*/ Serializable{ this.loadOnCacheMiss = loadOnCacheMiss; } + public void setPrincipal(Serializable principal){ + this.principal = principal; + } + //@Override public void toData(DataOutput out) throws IOException { DataSerializer.writeString(command,out); @@ -192,6 +200,7 @@ public class DataCommandRequest implements /*Data*/ Serializable{ DataSerializer.writeString(removeAllKeys,out); DataSerializer.writeBoolean(recursive,out); DataSerializer.writeBoolean(loadOnCacheMiss,out); + DataSerializer.writeObject(principal, out); } //@Override @@ -206,6 +215,7 @@ public class DataCommandRequest implements /*Data*/ Serializable{ removeAllKeys = DataSerializer.readString(in); recursive = DataSerializer.readBoolean(in); loadOnCacheMiss = DataSerializer.readBoolean(in); + principal = DataSerializer.readObject(in); } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java index e6482c1..2708242 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/management/internal/cli/functions/DataCommandFunction.java @@ -17,6 +17,7 @@ package com.gemstone.gemfire.management.internal.cli.functions; import java.io.IOException; +import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -28,6 +29,7 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.lang.StringUtils; import org.apache.logging.log4j.Logger; +import org.apache.shiro.subject.Subject; import org.json.JSONArray; import com.gemstone.gemfire.cache.Cache; @@ -98,7 +100,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt private static final int NESTED_JSON_LENGTH = 20; private SecurityService securityService = IntegratedSecurityService.getSecurityService(); - + @Override public String getId() { return DataCommandFunction.class.getName(); @@ -177,7 +179,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt String valueClass = request.getValueClass(); String regionName = request.getRegionName(); Boolean loadOnCacheMiss = request.isLoadOnCacheMiss(); - return get(key, keyClass, valueClass, regionName, loadOnCacheMiss); + return get(request.getPrincipal(), key, keyClass, valueClass, regionName, loadOnCacheMiss); } public DataCommandResult locateEntry(DataCommandRequest request) { @@ -202,7 +204,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt public DataCommandResult select(DataCommandRequest request) { String query = request.getQuery(); - return select(query); + return select(request.getPrincipal(), query); } /** @@ -221,7 +223,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt } @SuppressWarnings("rawtypes") - private DataCommandResult select(String queryString) { + private DataCommandResult select(Serializable principal, String queryString) { Cache cache = CacheFactory.getAnyInstance(); AtomicInteger nestedObjectCount = new AtomicInteger(0); @@ -253,7 +255,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt for (Iterator iter = selectResults.iterator(); iter.hasNext();) { Object object = iter.next(); // Post processing - object = this.securityService.postProcess(null, null, object, false); + object = this.securityService.postProcess(principal, null, null, object, false); if (object instanceof Struct) { StructImpl impl = (StructImpl) object; @@ -421,7 +423,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt } @SuppressWarnings({ "rawtypes" }) - public DataCommandResult get(String key, String keyClass, String valueClass, String regionName, Boolean loadOnCacheMiss) { + public DataCommandResult get(Serializable principal, String key, String keyClass, String valueClass, String regionName, Boolean loadOnCacheMiss) { Cache cache = CacheFactory.getAnyInstance(); @@ -458,7 +460,7 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt // run it through post processor. region.get will return the deserialized object already, so we don't need to // deserialize it anymore to pass it to the postProcessor - value = this.securityService.postProcess(regionName, keyObject, value, false); + value = this.securityService.postProcess(principal, regionName, keyObject, value, false); if (logger.isDebugEnabled()) logger.debug("Get for key {} value {}", key, value); @@ -943,6 +945,10 @@ public class DataCommandFunction extends FunctionAdapter implements InternalEnt DataCommandRequest request = new DataCommandRequest(); request.setCommand(CliStrings.QUERY); request.setQuery(query); + Subject subject = this.securityService.getSubject(); + if(subject!=null){ + request.setPrincipal((Serializable)subject.getPrincipal()); + } dataResult = DataCommands.callFunctionForRegion(request, function, members); dataResult.setInputQuery(query); return (dataResult); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java b/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java index 1a0e5de..3c50ecc 100644 --- a/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java +++ b/geode-core/src/main/java/org/apache/geode/security/PostProcessor.java @@ -17,7 +17,7 @@ package org.apache.geode.security; -import java.security.Principal; +import java.io.Serializable; import java.util.Properties; /** @@ -38,7 +38,8 @@ public interface PostProcessor { * Process the value before sending it to the requester * * @param principal - * The principal that's accessing the value + * The principal that's accessing the value. The type of the principal will depend on how you implemented + * your SecurityManager * @param regionName * The region that's been accessed. This could be null. * @param key @@ -48,7 +49,7 @@ public interface PostProcessor { * @return * the value that will be returned to the requester */ - Object processRegionValue(Principal principal, String regionName, Object key, Object value); + Object processRegionValue(Serializable principal, String regionName, Object key, Object value); /** * Give the implementation a chance to close the resources used. http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java b/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java index 273f2f1..9db4734 100644 --- a/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java +++ b/geode-core/src/main/java/org/apache/geode/security/SecurityManager.java @@ -16,7 +16,7 @@ */ package org.apache.geode.security; -import java.security.Principal; +import java.io.Serializable; import java.util.Properties; import com.gemstone.gemfire.distributed.DistributedSystem; @@ -46,10 +46,10 @@ public interface SecurityManager { * @param credentials * it contains the security-username and security-password as keys of the properties * @return - * the authenticated Principal object + * a serializable principal object * @throws AuthenticationFailedException */ - Principal authenticate(Properties credentials) throws AuthenticationFailedException; + Serializable authenticate(Properties credentials) throws AuthenticationFailedException; /** * Authorize the ResourcePermission for a given Principal @@ -60,7 +60,7 @@ public interface SecurityManager { * @return * true if authorized, false if not */ - default boolean authorize(Principal principal, ResourcePermission permission) { + default boolean authorize(Serializable principal, ResourcePermission permission) { return true; } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java b/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java index ce87bf8..bcf40cf 100644 --- a/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java +++ b/geode-core/src/main/java/org/apache/geode/security/templates/SamplePostProcessor.java @@ -16,6 +16,7 @@ */ package org.apache.geode.security.templates; +import java.io.Serializable; import java.security.Principal; import java.util.Properties; @@ -44,10 +45,17 @@ public class SamplePostProcessor implements PostProcessor{ * @return the processed value */ @Override - public Object processRegionValue(Principal principal, + public Object processRegionValue(Serializable principal, String regionName, Object key, Object value) { - return principal.getName()+"/"+regionName+"/"+key+"/"+value; + String name = null; + if(principal instanceof Principal){ + name = ((Principal) principal).getName(); + } + else{ + name = principal.toString(); + } + return name+"/"+regionName+"/"+key+"/"+value; } } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java b/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java index 83ac50e..6845647 100644 --- a/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java +++ b/geode-core/src/main/java/org/apache/geode/security/templates/SampleSecurityManager.java @@ -20,8 +20,8 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; +import java.io.Serializable; import java.io.StringWriter; -import java.security.Principal; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -33,8 +33,6 @@ import java.util.Set; import java.util.stream.Collectors; import java.util.stream.StreamSupport; -import javax.management.remote.JMXPrincipal; - import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.commons.io.IOUtils; @@ -106,10 +104,10 @@ public class SampleSecurityManager implements SecurityManager { private Map<String, User> userNameToUser; @Override - public boolean authorize(final Principal principal, final ResourcePermission context) { + public boolean authorize(final Serializable principal, final ResourcePermission context) { if (principal == null) return false; - User user = this.userNameToUser.get(principal.getName()); + User user = this.userNameToUser.get(principal.toString()); if (user == null) return false; // this user is not authorized to do anything // check if the user has this permission defined in the context @@ -150,7 +148,7 @@ public class SampleSecurityManager implements SecurityManager { } @Override - public Principal authenticate(final Properties credentials) throws AuthenticationFailedException { + public Serializable authenticate(final Properties credentials) throws AuthenticationFailedException { String user = credentials.getProperty(ResourceConstants.USER_NAME); String password = credentials.getProperty(ResourceConstants.PASSWORD); @@ -163,7 +161,7 @@ public class SampleSecurityManager implements SecurityManager { throw new AuthenticationFailedException("SampleSecurityManager: wrong username/password"); } - return new JMXPrincipal(user); + return user; } boolean initializeFromJson(final String json) {//throws IOException { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java index 4f0e260..e054206 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/AbstractSecureServerDUnitTest.java @@ -75,6 +75,7 @@ public class AbstractSecureServerDUnitTest extends JUnit4CacheTestCase { Properties props = new Properties(); props.setProperty(SampleSecurityManager.SECURITY_JSON, "com/gemstone/gemfire/management/internal/security/clientServer.json"); props.setProperty(SECURITY_MANAGER, SampleSecurityManager.class.getName()); +// props.setProperty(SECURITY_SHIRO_INIT, "shiro.ini"); props.setProperty(LOCATORS, ""); props.setProperty(MCAST_PORT, "0"); if (postProcessor!=null) { @@ -97,19 +98,18 @@ public class AbstractSecureServerDUnitTest extends JUnit4CacheTestCase { getSystem(props); - CacheFactory cf = null; - cf = new CacheFactory(); + CacheFactory cf = new CacheFactory(); cf.setPdxPersistent(pdxPersistent); cf.setPdxReadSerialized(pdxPersistent); Cache cache = getCache(cf); Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create(REGION_NAME); - CacheServer server1 = cache.addCacheServer(); - server1.setPort(0); - server1.start(); + CacheServer server = cache.addCacheServer(); + server.setPort(0); + server.start(); - this.serverPort = server1.getPort(); + this.serverPort = server.getPort(); for(Entry entry:values.entrySet()){ region.put(entry.getKey(), entry.getValue()); @@ -126,7 +126,7 @@ public class AbstractSecureServerDUnitTest extends JUnit4CacheTestCase { assertThatThrownBy(shouldRaiseThrowable).hasMessageContaining(permString); } - protected Properties createClientProperties(String userName, String password) { + public static Properties createClientProperties(String userName, String password) { Properties props = new Properties(); props.setProperty(UserPasswordAuthInit.USER_NAME, userName); props.setProperty(UserPasswordAuthInit.PASSWORD, password); @@ -137,7 +137,7 @@ public class AbstractSecureServerDUnitTest extends JUnit4CacheTestCase { return props; } - protected ClientCache createClientCache(String username, String password, int serverPort){ + public static ClientCache createClientCache(String username, String password, int serverPort){ ClientCache cache = new ClientCacheFactory(createClientProperties(username, password)) .setPoolSubscriptionEnabled(true) .addPoolServer("localhost", serverPort) http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java b/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java index b428144..d456516 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/NoShowValue1PostProcessor.java @@ -16,14 +16,14 @@ */ package com.gemstone.gemfire.security; -import java.security.Principal; +import java.io.Serializable; import org.apache.geode.security.PostProcessor; public class NoShowValue1PostProcessor implements PostProcessor { @Override - public Object processRegionValue(final Principal principal, + public Object processRegionValue(final Serializable principal, final String regionName, final Object key, final Object value) { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java new file mode 100644 index 0000000..5b4f3ac --- /dev/null +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXGfshPostProcessorOnRemoteServerTest.java @@ -0,0 +1,142 @@ +package com.gemstone.gemfire.security; + +import static com.gemstone.gemfire.distributed.ConfigurationProperties.*; +import static org.junit.Assert.*; + +import java.io.File; +import java.util.Properties; +import java.util.concurrent.TimeUnit; + +import com.jayway.awaitility.Awaitility; +import org.apache.geode.security.templates.SampleSecurityManager; +import org.junit.Before; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.CacheFactory; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionShortcut; +import com.gemstone.gemfire.cache.server.CacheServer; +import com.gemstone.gemfire.distributed.Locator; +import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem; +import com.gemstone.gemfire.internal.AvailablePortHelper; +import com.gemstone.gemfire.internal.security.GeodeSecurityUtil; +import com.gemstone.gemfire.management.ManagementService; +import com.gemstone.gemfire.management.cli.Result.Status; +import com.gemstone.gemfire.management.internal.cli.CliUtil; +import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh; +import com.gemstone.gemfire.management.internal.cli.i18n.CliStrings; +import com.gemstone.gemfire.management.internal.cli.result.CommandResult; +import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder; +import com.gemstone.gemfire.pdx.SimpleClass; +import com.gemstone.gemfire.security.templates.UserPasswordAuthInit; +import com.gemstone.gemfire.test.dunit.Host; +import com.gemstone.gemfire.test.dunit.VM; +import com.gemstone.gemfire.test.dunit.internal.JUnit4DistributedTestCase; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +@Category({ DistributedTest.class, SecurityTest.class }) +public class PDXGfshPostProcessorOnRemoteServerTest extends JUnit4DistributedTestCase { + protected static final String REGION_NAME = "AuthRegion"; + protected VM locator = null; + protected VM server = null; + + @Before + public void before() throws Exception { + final Host host = Host.getHost(0); + this.locator = host.getVM(0); + this.server = host.getVM(1); + } + + @Test + public void testGfshCommand() throws Exception{ + // set up locator with security + int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2); + int locatorPort = ports[0]; + int jmxPort = ports[1]; + locator.invoke(()->{ + Properties props = new Properties(); + props.setProperty(SampleSecurityManager.SECURITY_JSON, "com/gemstone/gemfire/management/internal/security/clientServer.json"); + props.setProperty(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + props.setProperty(MCAST_PORT, "0"); + props.put(JMX_MANAGER, "true"); + props.put(JMX_MANAGER_START, "true"); + props.put(JMX_MANAGER_PORT, jmxPort+""); + props.setProperty(SECURITY_POST_PROCESSOR, PDXPostProcessor.class.getName()); + Locator.startLocatorAndDS(locatorPort, new File("locator.log"), props); + }); + + // set up server with security + String locators = "localhost[" + locatorPort + "]"; + server.invoke(()->{ + Properties props = new Properties(); + props.setProperty(MCAST_PORT, "0"); + props.setProperty(LOCATORS, locators); + props.setProperty(SECURITY_MANAGER, SampleSecurityManager.class.getName()); + props.setProperty(SampleSecurityManager.SECURITY_JSON, "com/gemstone/gemfire/management/internal/security/clientServer.json"); + props.setProperty(SECURITY_POST_PROCESSOR, PDXPostProcessor.class.getName()); + + // the following are needed for peer-to-peer authentication + props.setProperty(SECURITY_PEER_AUTH_INIT, UserPasswordAuthInit.class.getName()); + props.setProperty("security-username", "super-user"); + props.setProperty("security-password", "1234567"); + InternalDistributedSystem ds = getSystem(props); + + Cache cache = CacheFactory.create(ds); + Region region = cache.createRegionFactory(RegionShortcut.REPLICATE).create(REGION_NAME); + + CacheServer server = cache.addCacheServer(); + server.setPort(0); + server.start(); + + for(int i=0; i<5; i++){ + SimpleClass obj = new SimpleClass(i, (byte)i); + region.put("key"+i, obj); + } + }); + + // wait until the region bean is visible + locator.invoke(()->{ + Awaitility.await().pollInterval(500, TimeUnit.MICROSECONDS).atMost(5, TimeUnit.SECONDS).until(()->{ + Cache cache = CacheFactory.getAnyInstance(); + Object bean = ManagementService.getManagementService(cache).getDistributedRegionMXBean("/"+REGION_NAME); + return bean != null; + }); + }); + + // run gfsh command in this vm + CliUtil.isGfshVM = true; + String shellId = getClass().getSimpleName(); + HeadlessGfsh gfsh = new HeadlessGfsh(shellId, 30, "gfsh_files"); + + // connect to the jmx server + final CommandStringBuilder connectCommand = new CommandStringBuilder(CliStrings.CONNECT); + connectCommand.addOption(CliStrings.CONNECT__USERNAME, "dataUser"); + connectCommand.addOption(CliStrings.CONNECT__PASSWORD, "1234567"); + + String endpoint = "localhost[" + jmxPort + "]"; + connectCommand.addOption(CliStrings.CONNECT__JMX_MANAGER, endpoint); + + gfsh.executeCommand(connectCommand.toString()); + CommandResult result = (CommandResult)gfsh.getResult(); + + // get command + gfsh.executeCommand("get --key=key1 --region=AuthRegion"); + result = (CommandResult) gfsh.getResult(); + assertEquals(result.getStatus(), Status.OK); + assertTrue(result.getContent().toString().contains(SimpleClass.class.getName())); + + gfsh.executeCommand("query --query=\"select * from /AuthRegion\""); + result = (CommandResult)gfsh.getResult(); + + CliUtil.isGfshVM = false; + server.invoke(()-> { + PDXPostProcessor pp = (PDXPostProcessor) GeodeSecurityUtil.getPostProcessor(); + // verify that the post processor is called 6 times. (5 for the query, 1 for the get) + assertEquals(pp.getCount(), 6); + }); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java index 5609a21..c51c9d8 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/PDXPostProcessor.java @@ -16,9 +16,9 @@ */ package com.gemstone.gemfire.security; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; -import java.security.Principal; +import java.io.Serializable; import java.util.Arrays; import java.util.Properties; @@ -38,7 +38,7 @@ public class PDXPostProcessor implements PostProcessor{ count = 0; } @Override - public Object processRegionValue(final Principal principal, + public Object processRegionValue(final Serializable principal, final String regionName, final Object key, final Object value) { http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/774044ee/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java b/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java index 6d04a0d..31ebde5 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/security/SpySecurityManager.java @@ -16,7 +16,7 @@ */ package com.gemstone.gemfire.security; -import java.security.Principal; +import java.io.Serializable; import java.util.Properties; import org.apache.geode.security.SecurityManager; @@ -32,7 +32,7 @@ public class SpySecurityManager implements SecurityManager { } @Override - public Principal authenticate(final Properties props) throws AuthenticationFailedException { + public Serializable authenticate(final Properties props) throws AuthenticationFailedException { return null; }