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/05/10 20:06:41 UTC
incubator-geode git commit: GEODE-1373: resolve the shiro subject in
JMX AccessControlContext first
Repository: incubator-geode
Updated Branches:
refs/heads/develop bcf7c94fb -> 9a7705407
GEODE-1373: resolve the shiro subject in JMX AccessControlContext first
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/9a770540
Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/9a770540
Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/9a770540
Branch: refs/heads/develop
Commit: 9a770540795691fb16a5ef5fef6dbb64c7e5183d
Parents: bcf7c94
Author: Jinmei Liao <ji...@pivotal.io>
Authored: Mon May 9 21:31:02 2016 -0700
Committer: Jinmei Liao <ji...@pivotal.io>
Committed: Tue May 10 13:06:12 2016 -0700
----------------------------------------------------------------------
.../internal/security/GeodeSecurityUtil.java | 69 ++++++++++++++++----
.../security/shiro/JMXShiroAuthenticator.java | 13 +++-
.../internal/security/shiro/ShiroPrincipal.java | 39 +++++++++++
3 files changed, 108 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9a770540/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 1f1f4eb..6e10f3f 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
@@ -17,12 +17,15 @@
package com.gemstone.gemfire.internal.security;
+import java.security.AccessController;
+import java.util.Set;
import java.util.concurrent.Callable;
import com.gemstone.gemfire.cache.operations.OperationContext;
import com.gemstone.gemfire.cache.operations.OperationContext.OperationCode;
import com.gemstone.gemfire.cache.operations.OperationContext.Resource;
import com.gemstone.gemfire.internal.logging.LogService;
+import com.gemstone.gemfire.internal.security.shiro.ShiroPrincipal;
import com.gemstone.gemfire.management.internal.security.ResourceOperation;
import com.gemstone.gemfire.management.internal.security.ResourceOperationContext;
import com.gemstone.gemfire.security.AuthenticationFailedException;
@@ -41,9 +44,15 @@ public class GeodeSecurityUtil {
private static Logger logger = LogService.getLogger();
- public static void login(String username, String password){
- if(!isShiroConfigured())
- return;
+ /**
+ *
+ * @param username
+ * @param password
+ * @return null if security is not enabled, otherwise return a shiro subject
+ */
+ public static Subject login(String username, String password){
+ if(!isSecured())
+ return null;
Subject currentUser = SecurityUtils.getSubject();
@@ -56,13 +65,52 @@ public class GeodeSecurityUtil {
logger.info(e.getMessage(), e);
throw new AuthenticationFailedException(e.getMessage(), e);
}
+
+ return currentUser;
+ }
+
+ /**
+ * 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.
+ *
+ * @return the shiro subject, null if security is not enabled
+ */
+ public static Subject getSubject(){
+ if(!isSecured())
+ return null;
+
+ Subject currentUser = null;
+
+ // First try get the principal out of AccessControlContext instead of Shiro's Thread context
+ // since threads can be shared between JMX clients.
+ javax.security.auth.Subject jmxSubject =
+ javax.security.auth.Subject.getSubject(AccessController.getContext());
+
+ if(jmxSubject!=null){
+ Set<ShiroPrincipal> principals = jmxSubject.getPrincipals(ShiroPrincipal.class);
+ if(principals.size()>0){
+ ShiroPrincipal principal = principals.iterator().next();
+ currentUser = principal.getSubject();
+ ThreadContext.bind(currentUser);
+ return currentUser;
+ }
+ }
+
+ // in other cases like admin rest call or pulse authorization
+ currentUser = SecurityUtils.getSubject();
+
+ if(currentUser==null || currentUser.getPrincipal()==null){
+ throw new GemFireSecurityException("Error: Anonymous User");
+ }
+
+ return currentUser;
}
public static void logout(){
- if(!isShiroConfigured())
+ Subject currentUser = getSubject();
+ if(currentUser==null)
return;
- Subject currentUser = SecurityUtils.getSubject();
try {
logger.info("Logging out "+currentUser.getPrincipal());
currentUser.logout();
@@ -76,10 +124,10 @@ public class GeodeSecurityUtil {
}
public static Callable associateWith(Callable callable){
- if(!isShiroConfigured())
+ Subject currentUser = getSubject();
+ if(currentUser==null)
return callable;
- Subject currentUser = SecurityUtils.getSubject();
return currentUser.associateWith(callable);
}
@@ -140,11 +188,10 @@ public class GeodeSecurityUtil {
if(context.getResource()== Resource.NULL && context.getOperationCode()== OperationCode.NULL)
return;
- if(!isShiroConfigured())
+ Subject currentUser = getSubject();
+ if(currentUser==null)
return;
-
- Subject currentUser = SecurityUtils.getSubject();
try {
currentUser.checkPermission(context);
}
@@ -154,7 +201,7 @@ public class GeodeSecurityUtil {
}
}
- private static boolean isShiroConfigured(){
+ private static boolean isSecured(){
try{
SecurityUtils.getSecurityManager();
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9a770540/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java
index 4a4cc28..984a2bf 100644
--- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/JMXShiroAuthenticator.java
@@ -18,6 +18,7 @@ package com.gemstone.gemfire.internal.security.shiro;
import static com.gemstone.gemfire.management.internal.security.ResourceConstants.*;
+import java.security.Principal;
import java.util.Collections;
import java.util.Properties;
import javax.management.Notification;
@@ -50,9 +51,17 @@ public class JMXShiroAuthenticator implements JMXAuthenticator, NotificationList
throw new SecurityException(WRONGE_CREDENTIALS_MESSAGE);
}
- GeodeSecurityUtil.login(username, password);
+ org.apache.shiro.subject.Subject shiroSubject = GeodeSecurityUtil.login(username, password);
+ Principal principal;
- return new Subject(true, Collections.singleton(new JMXPrincipal(username)), Collections.EMPTY_SET,
+ if(shiroSubject==null){
+ principal = new JMXPrincipal(username);
+ }
+ else{
+ principal = new ShiroPrincipal(shiroSubject);
+ }
+
+ return new Subject(true, Collections.singleton(principal), Collections.EMPTY_SET,
Collections.EMPTY_SET);
}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/9a770540/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java
new file mode 100644
index 0000000..8413ebb
--- /dev/null
+++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java
@@ -0,0 +1,39 @@
+/*
+ * 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.internal.security.shiro;
+
+import java.security.Principal;
+
+import org.apache.shiro.subject.Subject;
+
+public class ShiroPrincipal implements Principal {
+ private Subject subject;
+
+ public ShiroPrincipal(Subject subject){
+ this.subject = subject;
+ }
+
+ @Override
+ public String getName() {
+ return subject.toString();
+ }
+
+ public Subject getSubject(){
+ return subject;
+ }
+}