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;