You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ji...@apache.org on 2016/07/18 17:05:57 UTC

[2/2] incubator-geode git commit: GEODE-1571: have auth-init accept either a constructor or a static factory method.

GEODE-1571: have auth-init accept either a constructor or a static factory method.


Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/d200d708
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/d200d708
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/d200d708

Branch: refs/heads/develop
Commit: d200d70845649d14b71dab67ee17826017194e80
Parents: 8341267
Author: Jinmei Liao <ji...@pivotal.io>
Authored: Wed Jul 13 16:30:21 2016 -0700
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Mon Jul 18 10:04:44 2016 -0700

----------------------------------------------------------------------
 .../membership/gms/auth/GMSAuthenticator.java   | 24 +++----
 .../internal/cache/tier/sockets/HandShake.java  | 20 +++---
 .../internal/security/GeodeSecurityUtil.java    | 66 +++++++++++++++++---
 .../security/shiro/CustomAuthRealm.java         |  6 +-
 .../gemfire/security/AuthInitialize.java        | 12 +++-
 .../apache/geode/security/GeodePermission.java  | 21 +++++++
 .../apache/geode/security/PostProcessor.java    |  2 +-
 .../security/templates/SamplePostProcessor.java | 16 ++++-
 .../security/GeodeSecurityUtilTest.java         | 41 ++++++++++--
 9 files changed, 163 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java
index b82fdb1..f16a722 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/distributed/internal/membership/gms/auth/GMSAuthenticator.java
@@ -16,6 +16,14 @@
  */
 package com.gemstone.gemfire.distributed.internal.membership.gms.auth;
 
+import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
+import static com.gemstone.gemfire.internal.i18n.LocalizedStrings.*;
+
+import java.lang.reflect.Method;
+import java.security.Principal;
+import java.util.Properties;
+import java.util.Set;
+
 import com.gemstone.gemfire.LogWriter;
 import com.gemstone.gemfire.distributed.DistributedMember;
 import com.gemstone.gemfire.distributed.internal.DistributionConfig;
@@ -26,19 +34,12 @@ import com.gemstone.gemfire.distributed.internal.membership.gms.interfaces.Authe
 import com.gemstone.gemfire.internal.ClassLoadUtil;
 import com.gemstone.gemfire.internal.i18n.LocalizedStrings;
 import com.gemstone.gemfire.internal.logging.InternalLogWriter;
+import com.gemstone.gemfire.internal.security.GeodeSecurityUtil;
 import com.gemstone.gemfire.security.AuthInitialize;
 import com.gemstone.gemfire.security.AuthenticationFailedException;
 import com.gemstone.gemfire.security.AuthenticationRequiredException;
 import com.gemstone.gemfire.security.GemFireSecurityException;
 
-import java.lang.reflect.Method;
-import java.security.Principal;
-import java.util.Properties;
-import java.util.Set;
-
-import static com.gemstone.gemfire.internal.i18n.LocalizedStrings.*;
-import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
-
 // static messages
 
 public class GMSAuthenticator implements Authenticator {
@@ -195,12 +196,7 @@ public class GMSAuthenticator implements Authenticator {
 
     try {
       if (authMethod != null && authMethod.length() > 0) {
-        Method getter = ClassLoadUtil.methodFromName(authMethod);
-        AuthInitialize auth = (AuthInitialize)getter.invoke(null, (Object[]) null);
-        if (auth == null) {
-          throw new AuthenticationRequiredException(AUTH_FAILED_TO_ACQUIRE_AUTHINITIALIZE_INSTANCE.toLocalizedString(authMethod));
-        }
-
+        AuthInitialize auth = GeodeSecurityUtil.getObjectOfType(authMethod, AuthInitialize.class);
         try {
           LogWriter logWriter = services.getLogWriter();
           LogWriter securityLogWriter = services.getSecurityLogWriter();

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/HandShake.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/HandShake.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/HandShake.java
index a2951f5..c8aeacc 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/HandShake.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/tier/sockets/HandShake.java
@@ -1599,19 +1599,13 @@ public class HandShake implements ClientHandShake
     Properties credentials = null;
     try {
       if (authInitMethod != null && authInitMethod.length() > 0) {
-        Method instanceGetter = ClassLoadUtil.methodFromName(authInitMethod);
-        AuthInitialize auth = (AuthInitialize)instanceGetter.invoke(null,
-            (Object[])null);
-        if (auth != null) {
-          auth.init(logWriter, 
-                    securityLogWriter);
-          try {
-            credentials = auth.getCredentials(securityProperties, server,
-                isPeer);
-          }
-          finally {
-            auth.close();
-          }
+        AuthInitialize auth = GeodeSecurityUtil.getObjectOfType(authInitMethod, AuthInitialize.class);
+        auth.init(logWriter, securityLogWriter);
+        try {
+          credentials = auth.getCredentials(securityProperties, server, isPeer);
+        }
+        finally {
+          auth.close();
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/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 8707a78..2962240 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,13 +19,20 @@ package com.gemstone.gemfire.internal.security;
 
 import static com.gemstone.gemfire.distributed.ConfigurationProperties.*;
 
+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.NullArgumentException;
 import org.apache.commons.lang.StringUtils;
+import org.apache.geode.security.GeodePermission;
+import org.apache.geode.security.GeodePermission.Operation;
+import org.apache.geode.security.GeodePermission.Resource;
+import org.apache.geode.security.PostProcessor;
+import org.apache.geode.security.SecurityManager;
 import org.apache.logging.log4j.Logger;
 import org.apache.shiro.SecurityUtils;
 import org.apache.shiro.ShiroException;
@@ -47,12 +54,7 @@ import com.gemstone.gemfire.internal.security.shiro.ShiroPrincipal;
 import com.gemstone.gemfire.management.internal.security.ResourceOperation;
 import com.gemstone.gemfire.security.AuthenticationFailedException;
 import com.gemstone.gemfire.security.GemFireSecurityException;
-import org.apache.geode.security.GeodePermission;
-import org.apache.geode.security.GeodePermission.Operation;
-import org.apache.geode.security.GeodePermission.Resource;
 import com.gemstone.gemfire.security.NotAuthorizedException;
-import org.apache.geode.security.PostProcessor;
-import org.apache.geode.security.SecurityManager;
 
 public class GeodeSecurityUtil {
 
@@ -310,7 +312,7 @@ public class GeodeSecurityUtil {
 
     // only set up shiro realm if user has implemented SecurityManager
     else if (!StringUtils.isBlank(securityConfig)) {
-      securityManager = getObjectOfType(securityConfig, SecurityManager.class);
+      securityManager = getObjectOfTypeFromClassName(securityConfig, SecurityManager.class);
       securityManager.init(securityProps);
       Realm realm = new CustomAuthRealm(securityManager);
       org.apache.shiro.mgt.SecurityManager shiroManager = new DefaultSecurityManager(realm);
@@ -323,7 +325,7 @@ public class GeodeSecurityUtil {
     // this initializes the post processor
     String customPostProcessor = securityProps.getProperty(SECURITY_POST_PROCESSOR);
     if( !StringUtils.isBlank(customPostProcessor)) {
-      postProcessor = getObjectOfType(customPostProcessor, PostProcessor.class);
+      postProcessor = getObjectOfTypeFromClassName(customPostProcessor, PostProcessor.class);
       postProcessor.init(securityProps);
     }
     else{
@@ -367,7 +369,14 @@ public class GeodeSecurityUtil {
   }
 
 
-  public static <T> T getObjectOfType(String className, Class<T> expectedClazz) {
+  /**
+   * this method would never return null, it either throws an exception or returns an object
+   * @param className
+   * @param expectedClazz
+   * @param <T>
+   * @return
+   */
+  public static <T> T getObjectOfTypeFromClassName(String className, Class<T> expectedClazz) {
     Class actualClass = null;
     try {
       actualClass = ClassLoadUtil.classFromName(className);
@@ -389,6 +398,47 @@ public class GeodeSecurityUtil {
     return actualObject;
   }
 
+  /**
+   * this method would never return null, it either throws an exception or returns an object
+   * @param factoryMethodName
+   * @param expectedClazz
+   * @param <T>
+   * @return
+   */
+  public static <T> T getObjectOfTypeFromFactoryMethod(String factoryMethodName, Class<T> expectedClazz){
+    try {
+      Method factoryMethod = ClassLoadUtil.methodFromName(factoryMethodName);
+      T actualObject = (T)factoryMethod.invoke(null, (Object[])null);
+
+      if(actualObject == null){
+        throw new NullArgumentException("Factory method "+ factoryMethodName + " should not return null.");
+      }
+
+      return actualObject;
+    } catch (Exception e) {
+      throw new GemFireSecurityException(e.toString(), e);
+    }
+  }
+
+  /**
+   * this method would never return null, it either throws an exception or returns an object
+   * @param classOrMethod
+   * @param expectedClazz
+   * @param <T>
+   * @return an object of type expectedClazz. This method would never return null. It either returns an non-null
+   * object or throws exception.
+   */
+  public static <T> T getObjectOfType(String classOrMethod, Class<T> expectedClazz) {
+    T object = null;
+    try{
+      object = getObjectOfTypeFromClassName(classOrMethod, expectedClazz);
+    }
+    catch (Exception e){
+      object = getObjectOfTypeFromFactoryMethod(classOrMethod, expectedClazz);
+    }
+    return object;
+  }
+
   public static SecurityManager getSecurityManager(){
     return securityManager;
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/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 3d6275b..db07fe0 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
@@ -19,6 +19,8 @@ package com.gemstone.gemfire.internal.security.shiro;
 import java.security.Principal;
 import java.util.Properties;
 
+import org.apache.geode.security.GeodePermission;
+import org.apache.geode.security.SecurityManager;
 import org.apache.shiro.authc.AuthenticationException;
 import org.apache.shiro.authc.AuthenticationInfo;
 import org.apache.shiro.authc.AuthenticationToken;
@@ -31,8 +33,6 @@ import org.apache.shiro.subject.PrincipalCollection;
 
 import com.gemstone.gemfire.internal.security.GeodeSecurityUtil;
 import com.gemstone.gemfire.management.internal.security.ResourceConstants;
-import org.apache.geode.security.SecurityManager;
-import org.apache.geode.security.GeodePermission;
 
 public class CustomAuthRealm extends AuthorizingRealm{
 
@@ -45,7 +45,7 @@ public class CustomAuthRealm extends AuthorizingRealm{
   }
 
   public CustomAuthRealm (String authenticatorFactory) {
-    this.securityManager = GeodeSecurityUtil.getObjectOfType(authenticatorFactory, SecurityManager.class);
+    this.securityManager = GeodeSecurityUtil.getObjectOfTypeFromClassName(authenticatorFactory, SecurityManager.class);
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/geode-core/src/main/java/com/gemstone/gemfire/security/AuthInitialize.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/AuthInitialize.java b/geode-core/src/main/java/com/gemstone/gemfire/security/AuthInitialize.java
index 400c665..e92772b 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/security/AuthInitialize.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/AuthInitialize.java
@@ -23,6 +23,7 @@ import com.gemstone.gemfire.LogWriter;
 import com.gemstone.gemfire.cache.CacheCallback;
 import com.gemstone.gemfire.distributed.DistributedMember;
 import com.gemstone.gemfire.distributed.DistributedSystem;
+import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
 
 // TODO Add example usage of this interface and configuration details
 /**
@@ -49,11 +50,21 @@ public interface AuthInitialize extends CacheCallback {
    * 
    * @throws AuthenticationFailedException
    *                 if some exception occurs during the initialization
+   *
+   *  @deprecated since Geode 1.0, use init()
    */
   public void init(LogWriter systemLogger, LogWriter securityLogger)
       throws AuthenticationFailedException;
 
   /**
+   * @since Geode 1.0. implement this method instead of init with logwriters.
+   * Implementation should use log4j instead of these loggers.
+   */
+  default public void init(){
+    GemFireCacheImpl cache = GemFireCacheImpl.getInstance();
+    init(cache.getLogger(), cache.getSecurityLogger());
+  }
+  /**
    * Initialize with the given set of security properties and return the
    * credentials for the peer/client as properties.
    * 
@@ -83,5 +94,4 @@ public interface AuthInitialize extends CacheCallback {
   public Properties getCredentials(Properties securityProps,
       DistributedMember server, boolean isPeer)
       throws AuthenticationFailedException;
-
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/geode-core/src/main/java/org/apache/geode/security/GeodePermission.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/security/GeodePermission.java b/geode-core/src/main/java/org/apache/geode/security/GeodePermission.java
index 866b14e..0a777a8 100644
--- a/geode-core/src/main/java/org/apache/geode/security/GeodePermission.java
+++ b/geode-core/src/main/java/org/apache/geode/security/GeodePermission.java
@@ -19,6 +19,11 @@ package org.apache.geode.security;
 
 import org.apache.shiro.authz.permission.WildcardPermission;
 
+/**
+ * GeodePermission defines the resource, the operation, the region and the key involved in the action to be authorized.
+ *
+ * It is passed to the SecurityManager for the implementation to decide whether to grant a user this permission or not.
+ */
 public class GeodePermission extends WildcardPermission {
 
   public static String ALL_REGIONS = "*";
@@ -37,18 +42,34 @@ public class GeodePermission extends WildcardPermission {
     READ
   }
 
+  /**
+   * Returns the resource, could be either DATA or CLUSTER
+   * @return
+   */
   public Resource getResource() {
     return resource;
   }
 
+  /**
+   * Returns the operation, could be either MANAGE, WRITE or READ
+   * @return
+   */
   public Operation getOperation() {
     return operation;
   }
 
+  /**
+   * returns the regionName, could be "*", meaning all regions
+   * @return
+   */
   public String getRegionName() {
     return regionName;
   }
 
+  /**
+   * returns the key, could be "*" meaning all keys.
+   * @return
+   */
   public String getKey() {
     return key;
   }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/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 0f13b47..1a0e5de 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
@@ -44,7 +44,7 @@ public interface PostProcessor {
    * @param key
    *        the key of the value that's been accessed. This could be null.
    * @param value
-   *        the value, this could be null.
+   *        the original value. The orginal value could be null as well.
    * @return
    *        the value that will be returned to the requester
    */

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/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 7e078da..8f61db7 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
@@ -22,14 +22,28 @@ import java.util.Properties;
 
 import org.apache.geode.security.PostProcessor;
 
+/**
+ * This is example that implements PostProcessor
+ */
 public class SamplePostProcessor implements PostProcessor{
-  public static String MASK = "****";
 
   @Override
   public void init(final Properties securityProps) {
 
   }
 
+  /**
+   * this simply modifies the value with all the parameter values
+   * @param principal
+   *        The principal that's accessing the value
+   * @param regionName
+   *        The region that's been accessed. This could be null.
+   * @param key
+   *        the key of the value that's been accessed. This could be null.
+   * @param value
+   *        the value, this could be null.
+   * @return
+   */
   @Override
   public Object processRegionValue(Principal principal,
                                    String regionName,

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/d200d708/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java b/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java
index d1dd466..6c1f1f2 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/internal/security/GeodeSecurityUtilTest.java
@@ -18,22 +18,23 @@ package com.gemstone.gemfire.internal.security;
 
 
 import static org.assertj.core.api.Java6Assertions.*;
+import static org.junit.Assert.assertNotNull;
 
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
 import com.gemstone.gemfire.security.GemFireSecurityException;
-import com.gemstone.gemfire.test.junit.categories.SecurityTest;
 import com.gemstone.gemfire.test.junit.categories.UnitTest;
 
-@Category({ UnitTest.class, SecurityTest.class })
+@Category(UnitTest.class)
 public class GeodeSecurityUtilTest {
 
   @Test
-  public void testGetObject(){
+  public void testGetObjectFromConstructor(){
     String string = GeodeSecurityUtil.getObjectOfType(String.class.getName(), String.class);
-
+    assertNotNull(string);
     CharSequence charSequence = GeodeSecurityUtil.getObjectOfType(String.class.getName(), CharSequence.class);
+    assertNotNull(charSequence);
 
     assertThatThrownBy(() -> GeodeSecurityUtil.getObjectOfType("com.abc.testString", String.class)).isInstanceOf(GemFireSecurityException.class);
 
@@ -45,4 +46,36 @@ public class GeodeSecurityUtilTest {
 
     assertThatThrownBy(() -> GeodeSecurityUtil.getObjectOfType("  ", String.class)).isInstanceOf(GemFireSecurityException.class);
   }
+
+  @Test
+  public void testGetObjectFromFactoryMethod(){
+    String string = GeodeSecurityUtil.getObjectOfType(Factories.class.getName()+".getString", String.class);
+    assertNotNull(string);
+    CharSequence charSequence = GeodeSecurityUtil.getObjectOfType(Factories.class.getName()+".getString", String.class);
+    assertNotNull(charSequence);
+
+    assertThatThrownBy(() -> GeodeSecurityUtil.getObjectOfType(Factories.class.getName()+".getStringNonStatic", String.class))
+      .isInstanceOf(GemFireSecurityException.class);
+
+    assertThatThrownBy(() -> GeodeSecurityUtil.getObjectOfType(Factories.class.getName()+".getNullString", String.class))
+      .isInstanceOf(GemFireSecurityException.class);
+  }
+
+  private static class Factories{
+    public static String getString(){
+      return new String();
+    }
+
+    public static String getNullString(){
+      return null;
+    }
+
+    public String getStringNonStatic(){
+      return new String();
+    }
+
+    public static Boolean getBoolean(){
+      return Boolean.TRUE;
+    }
+  }
 }