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

[39/55] [abbrv] incubator-geode git commit: GEODE-1373: resolve the shiro subject in JMX AccessControlContext first

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/feature/GEODE-1153
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;
+  }
+}