[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; }
