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

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

Branch: refs/heads/karaf-4.0.x
Commit: 3877c00131302b9bd09a38e390bbf81c2f258a08
Parents: 78ee25b
Author: Grzegorz Grzybek <[email protected]>
Authored: Mon Feb 22 11:00:09 2016 +0100
Committer: Guillaume Nodet <[email protected]>
Committed: Mon Feb 29 11:00:20 2016 +0100

----------------------------------------------------------------------
 .../karaf/management/KarafMBeanServerGuard.java |  2 +-
 .../management/internal/BulkRequestContext.java | 32 ++++++++++++++++++++
 .../org/apache/karaf/util/jaas/JaasHelper.java  | 30 ++++++++++++------
 3 files changed, 53 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/karaf/blob/3877c001/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 b112c2f..4259326 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
@@ -234,7 +234,7 @@ public class KarafMBeanServerGuard implements 
InvocationHandler {
             return true;
         }
         for (String role : getRequiredRoles(context, objectName, methodName, 
signature)) {
-            if (JaasHelper.currentUserHasRole(role))
+            if (JaasHelper.currentUserHasRole(context.getPrincipals(), role))
                 return true;
         }
 

http://git-wip-us.apache.org/repos/asf/karaf/blob/3877c001/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..1b9145b 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<>();
+
     // 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;
+    }
+
 }

http://git-wip-us.apache.org/repos/asf/karaf/blob/3877c001/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java
----------------------------------------------------------------------
diff --git a/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java 
b/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java
index e193700..a4d2f13 100644
--- a/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java
+++ b/util/src/main/java/org/apache/karaf/util/jaas/JaasHelper.java
@@ -22,6 +22,7 @@ import java.security.PrivilegedAction;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
 import java.security.ProtectionDomain;
+import java.util.Set;
 
 import javax.security.auth.Subject;
 import javax.security.auth.SubjectDomainCombiner;
@@ -36,7 +37,24 @@ public class JaasHelper {
         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);
+    }
+
+    public static boolean currentUserHasRole(Set<Principal> principals, String 
requestedRole) {
+        if (ROLE_WILDCARD.equals(requestedRole)) {
+            return true;
+        }
+
         String clazz;
         String role;
         int index = requestedRole.indexOf(':');
@@ -47,15 +65,7 @@ public class JaasHelper {
             clazz = RolePrincipal.class.getName();
             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;
             }

Reply via email to