[KARAF-4351] Optimize JAAS ACC/Subject access in bulk RBAC calls

(cherry picked from commit fe2a82b1bc12c91e8f61e8ec1dc237e09aa0052c)
(cherry picked from commit 5b29a4466165b519637b9aa9e0b9c3bf0794b7b9)


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

Branch: refs/heads/karaf-3.0.x
Commit: e5753f614965964028cf6ae1ed44478cc185cffa
Parents: 4a058ec
Author: Grzegorz Grzybek <[email protected]>
Authored: Mon Feb 22 11:00:09 2016 +0100
Committer: Guillaume Nodet <[email protected]>
Committed: Mon Feb 29 10:47:14 2016 +0100

----------------------------------------------------------------------
 .../karaf/management/KarafMBeanServerGuard.java | 34 ++++++++++++--------
 .../management/internal/BulkRequestContext.java | 32 ++++++++++++++++++
 2 files changed, 52 insertions(+), 14 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/e5753f61/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
----------------------------------------------------------------------
diff --git 
a/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
 
b/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
index c90b6e7..12d7fc1 100644
--- 
a/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
+++ 
b/management/server/src/main/java/org/apache/karaf/management/KarafMBeanServerGuard.java
@@ -239,7 +239,7 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
             return true;
         }
         for (String role : getRequiredRoles(context, objectName, methodName, 
signature)) {
-            if (currentUserHasRole(role))
+            if (currentUserHasRole(context.getPrincipals(), role))
                 return true;
         }
 
@@ -453,12 +453,28 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
         res.add(JMX_ACL_PID_PREFIX); // this is the top PID (aka jmx.acl)
         return res;
     }
-
     static boolean currentUserHasRole(String requestedRole) {
         if (ROLE_WILDCARD.equals(requestedRole)) {
             return true;
         }
-        
+
+        AccessControlContext acc = AccessController.getContext();
+        if (acc == null) {
+            return false;
+        }
+        Subject subject = Subject.getSubject(acc);
+        if (subject == null) {
+            return false;
+        }
+
+        return currentUserHasRole(subject.getPrincipals(), requestedRole);
+    }
+
+    static boolean currentUserHasRole(Set<Principal> principals, String 
requestedRole) {
+        if (ROLE_WILDCARD.equals(requestedRole)) {
+            return true;
+        }
+
         String clazz;
         String role;
         int index = requestedRole.indexOf(':');
@@ -470,17 +486,7 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
             role = requestedRole;
         }
 
-        AccessControlContext acc = AccessController.getContext();
-        if (acc == null) {
-            return false;
-        }
-        Subject subject = Subject.getSubject(acc);
-
-        if (subject == null) {
-            return false;
-        }
-
-        for (Principal p : subject.getPrincipals()) {
+        for (Principal p : principals) {
             if (clazz.equals(p.getClass().getName()) && 
role.equals(p.getName())) {
                 return true;
             }

http://git-wip-us.apache.org/repos/asf/karaf/blob/e5753f61/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java
----------------------------------------------------------------------
diff --git 
a/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java
 
b/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java
index 1c72a60..59cb425 100644
--- 
a/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java
+++ 
b/management/server/src/main/java/org/apache/karaf/management/internal/BulkRequestContext.java
@@ -17,11 +17,18 @@
 package org.apache.karaf.management.internal;
 
 import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Principal;
 import java.util.ArrayList;
 import java.util.Dictionary;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
 
 import org.osgi.framework.InvalidSyntaxException;
 import org.osgi.service.cm.Configuration;
@@ -41,6 +48,11 @@ public class BulkRequestContext {
 
     private ConfigurationAdmin configAdmin;
 
+    // if there's AccessControlContext or subject, we can fail fast
+    private boolean anonymous = false;
+    // otherwise we can cache current subject's principals for faster access
+    private Set<Principal> principals = new HashSet<Principal>();
+
     // cache with lifecycle bound to BulkRequestContext instance
     private Map<String, Dictionary<String, Object>> cachedConfigurations = new 
HashMap<String, Dictionary<String, Object>>();
 
@@ -50,6 +62,18 @@ public class BulkRequestContext {
         BulkRequestContext context = new BulkRequestContext();
         context.configAdmin = configAdmin;
         try {
+            // check JAAS subject here
+            AccessControlContext acc = AccessController.getContext();
+            if (acc == null) {
+                context.anonymous = true;
+            } else {
+                Subject subject = Subject.getSubject(acc);
+                if (subject == null) {
+                    context.anonymous = true;
+                } else {
+                    context.principals.addAll(subject.getPrincipals());
+                }
+            }
             // list available ACL configs - valid for this instance only
             for (Configuration config : 
configAdmin.listConfigurations("(service.pid=jmx.acl*)")) {
                 context.allPids.add(config.getPid());
@@ -97,4 +121,12 @@ public class BulkRequestContext {
         return cachedConfigurations.get(generalPid);
     }
 
+    public boolean isAnonymous() {
+        return anonymous;
+    }
+
+    public Set<Principal> getPrincipals() {
+        return principals;
+    }
+
 }

Reply via email to