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/08 15:52:05 UTC

[45/50] [abbrv] incubator-geode git commit: Fixing close method

Fixing close 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/25a80da3
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/25a80da3
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/25a80da3

Branch: refs/heads/develop
Commit: 25a80da35e9da3d4fc93f8a180ba50f74f3988a7
Parents: 0fd2288
Author: gmeilen <gr...@gmail.com>
Authored: Thu Jul 7 13:53:44 2016 -0700
Committer: gmeilen <gr...@gmail.com>
Committed: Thu Jul 7 13:53:44 2016 -0700

----------------------------------------------------------------------
 .../internal/cache/GemFireCacheImpl.java        |   2 +-
 .../internal/security/GeodeSecurityUtil.java    |  21 +-
 .../security/shiro/CustomAuthRealm.java         |   1 +
 .../templates/SampleSecurityManager.java        | 261 +++++++++++++++++++
 ...edSecurityCacheLifecycleIntegrationTest.java |   3 +-
 5 files changed, 275 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/25a80da3/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
index 567f377..e39ffdd 100755
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/cache/GemFireCacheImpl.java
@@ -1899,7 +1899,7 @@ public class GemFireCacheImpl implements InternalCache, ClientCache, HasCachePer
       return;
     }
     final boolean isDebugEnabled = logger.isDebugEnabled();
-    GeodeSecurityUtil.close(system.getConfig().getSecurityProps());
+    GeodeSecurityUtil.close();
 
     synchronized (GemFireCacheImpl.class) {
       // bugfix for bug 36512 "GemFireCache.close is not thread safe"

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/25a80da3/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 ff32f92..d93c93f 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
@@ -60,6 +60,7 @@ public class GeodeSecurityUtil {
 
   private static Logger logger = LogService.getLogger();
 
+
   /**
    * It first looks the shiro subject in AccessControlContext since JMX will use multiple threads to process operations from the same client.
    * then it looks into Shiro's thead context.
@@ -284,6 +285,7 @@ public class GeodeSecurityUtil {
   }
 
   private static PostProcessor postProcessor;
+  private static SecurityManager securityManager;
 
   /**
    * initialize Shiro's Security Manager and Security Utilities
@@ -314,9 +316,9 @@ public class GeodeSecurityUtil {
 
     // only set up shiro realm if user has implemented SecurityManager
     else if (authenticatorObject != null && authenticatorObject instanceof SecurityManager) {
-      SecurityManager authenticator = (SecurityManager) authenticatorObject;
-      authenticator.init(securityProps);
-      Realm realm = new CustomAuthRealm(authenticator);
+      securityManager = (SecurityManager) authenticatorObject;
+      securityManager.init(securityProps);
+      Realm realm = new CustomAuthRealm(securityManager);
       org.apache.shiro.mgt.SecurityManager securityManager = new DefaultSecurityManager(realm);
       SecurityUtils.setSecurityManager(securityManager);
     }
@@ -337,15 +339,12 @@ public class GeodeSecurityUtil {
 
   }
 
-  public static void close(Properties securityProps) {
-    if (securityProps != null) {
-      String customAuthenticator = securityProps.getProperty(SECURITY_MANAGER);
-      Object authenticatorObject = getObject(customAuthenticator);
-      if (authenticatorObject != null && authenticatorObject instanceof SecurityManager) {
-        ((SecurityManager) authenticatorObject).close();
+  public static void close() {
+      if (securityManager != null) {
+        securityManager.close();
+        securityManager = null;
       }
-    }
-    return;
+
   }
 
   public static Object postProcess(String regionPath, Object key, Object result){

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/25a80da3/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 d80b936..98ca1f0 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
@@ -86,4 +86,5 @@ public class CustomAuthRealm extends AuthorizingRealm{
     return externalSecurity.authorize(principal, context);
   }
 
+
 }

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/25a80da3/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleSecurityManager.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleSecurityManager.java b/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleSecurityManager.java
new file mode 100644
index 0000000..a80782d
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/security/templates/SampleSecurityManager.java
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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
+ *
+ *      http://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 com.gemstone.gemfire.security.templates;
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+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;
+import org.apache.shiro.authz.Permission;
+
+import com.gemstone.gemfire.management.internal.security.ResourceConstants;
+import com.gemstone.gemfire.security.AccessControl;
+import com.gemstone.gemfire.security.AuthenticationFailedException;
+import com.gemstone.gemfire.security.Authenticator;
+import com.gemstone.gemfire.security.SecurityManager;
+import com.gemstone.gemfire.security.GeodePermission;
+import com.gemstone.gemfire.security.NotAuthorizedException;
+
+/**
+ * This class provides a sample implementation for authentication and authorization via the {@link AccessControl}
+ * and {@link Authenticator} interfaces.
+ *
+ * In order to use it, a Geode member must be started with the following properties:
+ * <p/>
+ * <code>
+ *   security-client-authenticator = com.gemstone.gemfire.security.examples.SampleSecurityManager.create
+ *   security-client-accessor = com.gemstone.gemfire.security.examples.SampleSecurityManager.create
+ * </code>
+ * <p/>
+ * The class is initialized with a JSON file called {@code security.json}. This file must exist on the classpath,
+ * so members should be started with an appropriate {@code --classpath} option.
+ * <p/>
+ * The format of the file is as follows:
+ * <pre>
+ * {
+ *   "roles": [
+ *     {
+ *       "name": "admin",
+ *       "operationsAllowed": [
+ *         "CLUSTER:MANAGE",
+ *         "DATA:MANAGE"
+ *       ]
+ *     },
+ *     {
+ *       "name": "readRegionA",
+ *       "operationsAllowed": [
+ *         "DATA:READ"
+ *       ],
+ *       "regions": ["RegionA", "RegionB"]
+ *     }
+ *   ]
+ *   "users": [
+ *     {
+ *       "name": "admin",
+ *       "password": "secret".
+ *       "roles": ["admin"]
+ *     },
+ *     {
+ *       "name": "guest",
+ *       "password": "guest",
+ *       "roles": ["readRegionA"]
+ *     }
+ *   ]
+ * }
+ * </pre>
+ */
+public class SampleSecurityManager
+  implements SecurityManager {
+
+  public static class Role {
+    List<GeodePermission> permissions = new ArrayList<>();
+    String name;
+    String serverGroup;
+  }
+
+  public static class User {
+    String name;
+    Set<Role> roles = new HashSet<>();
+    String pwd;
+  }
+
+  private static Map<String, User> acl = null;
+
+  public static SampleSecurityManager create() throws IOException {
+    if (acl == null) {
+      setUpWithJsonFile("security.json");
+    }
+    return new SampleSecurityManager();
+  }
+
+  public static void setUpWithJsonFile(String jsonFileName) throws IOException {
+    InputStream input = ClassLoader.getSystemResourceAsStream(jsonFileName);
+    if (input == null) {
+      throw new RuntimeException("Could not find the required JSON security file on the classpath: " + jsonFileName);
+    }
+
+    StringWriter writer = new StringWriter();
+    IOUtils.copy(input, writer, "UTF-8");
+    String json = writer.toString();
+    readSecurityDescriptor(json);
+  }
+
+  protected static void readSecurityDescriptor(String json) throws IOException {
+    ObjectMapper mapper = new ObjectMapper();
+    JsonNode jsonNode = mapper.readTree(json);
+    acl = new HashMap<>();
+    Map<String, Role> roleMap = readRoles(jsonNode);
+    readUsers(acl, jsonNode, roleMap);
+  }
+
+  private static void readUsers(Map<String, User> acl, JsonNode node, Map<String, Role> roleMap) {
+    for (JsonNode u : node.get("users")) {
+      User user = new User();
+      user.name = u.get("name").asText();
+
+      if (u.has("password")) {
+        user.pwd = u.get("password").asText();
+      } else {
+        user.pwd = user.name;
+      }
+
+      for (JsonNode r : u.get("roles")) {
+        user.roles.add(roleMap.get(r.asText()));
+      }
+
+      acl.put(user.name, user);
+    }
+  }
+
+  private static Map<String, Role> readRoles(JsonNode jsonNode) {
+    Map<String, Role> roleMap = new HashMap<>();
+    for (JsonNode r : jsonNode.get("roles")) {
+      Role role = new Role();
+      role.name = r.get("name").asText();
+      String regionNames = null;
+      String keys = null;
+
+      JsonNode regions = r.get("regions");
+      if (regions != null) {
+        if (regions.isArray()) {
+          regionNames = StreamSupport.stream(regions.spliterator(), false)
+              .map(JsonNode::asText)
+              .collect(Collectors.joining(","));
+        } else {
+          regionNames = regions.asText();
+        }
+      }
+
+      for (JsonNode op : r.get("operationsAllowed")) {
+        String[] parts = op.asText().split(":");
+        String resourcePart = (parts.length > 0) ? parts[0] : null;
+        String operationPart = (parts.length > 1) ? parts[1] : null;
+        if(parts.length>2){
+          regionNames = parts[2];
+        }
+        if(parts.length>3){
+          keys = parts[3];
+        }
+        String regionPart = (regionNames != null) ? regionNames : "*";
+        String keyPart = (keys !=null) ? keys : "*";
+
+        role.permissions.add(new GeodePermission(resourcePart, operationPart, regionPart, keyPart));
+      }
+
+      roleMap.put(role.name, role);
+
+      if (r.has("serverGroup")) {
+        role.serverGroup = r.get("serverGroup").asText();
+      }
+    }
+
+    return roleMap;
+  }
+  public static Map<String, User> getAcl() {
+    return acl;
+  }
+
+  private Principal principal = null;
+
+
+  @Override
+  public boolean authorize(Principal principal, GeodePermission context) {
+    if (principal == null) return false;
+
+    User user = acl.get(principal.getName());
+    if (user == null) return false; // this user is not authorized to do anything
+
+    // check if the user has this permission defined in the context
+    for (Role role : acl.get(user.name).roles) {
+      for (Permission permitted : role.permissions) {
+        if (permitted.implies(context)) {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  @Override
+  public void init(Properties props) throws NotAuthorizedException {
+  }
+
+  @Override
+  public Principal authenticate(Properties props) throws AuthenticationFailedException {
+    String user = props.getProperty(ResourceConstants.USER_NAME);
+    String pwd = props.getProperty(ResourceConstants.PASSWORD);
+
+    User userObj = acl.get(user);
+    if (userObj == null) {
+      throw new AuthenticationFailedException("Wrong username/password");
+    }
+
+    if (user != null && !userObj.pwd.equals(pwd) && !"".equals(user)) {
+      throw new AuthenticationFailedException("Wrong username/password");
+    }
+
+    return new JMXPrincipal(user);
+  }
+
+  protected static String readFile(String name) throws IOException {
+    File file = new File(name);
+    FileReader reader = new FileReader(file);
+    char[] buffer = new char[(int) file.length()];
+    reader.read(buffer);
+    String json = new String(buffer);
+    reader.close();
+    return json;
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/25a80da3/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleIntegrationTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleIntegrationTest.java b/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleIntegrationTest.java
index 96a4a51..0b97888 100644
--- a/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleIntegrationTest.java
+++ b/geode-core/src/test/java/com/gemstone/gemfire/security/IntegratedSecurityCacheLifecycleIntegrationTest.java
@@ -26,13 +26,14 @@ import java.util.Properties;
 import com.gemstone.gemfire.cache.Cache;
 import com.gemstone.gemfire.cache.CacheFactory;
 import com.gemstone.gemfire.test.junit.categories.IntegrationTest;
+import com.gemstone.gemfire.test.junit.categories.SecurityTest;
 
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.experimental.categories.Category;
 
-@Category(IntegrationTest.class)
+@Category({IntegrationTest.class, SecurityTest.class})
 public class IntegratedSecurityCacheLifecycleIntegrationTest {
 
   private static SpySecurityManager spySecurityManager;