You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by an...@apache.org on 2013/11/27 14:39:26 UTC

svn commit: r1546031 - in /jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak: osgi/ security/authorization/permission/ security/principal/ spi/lifecycle/ spi/security/ spi/security/authentication/token/ spi/security/principal/ spi/s...

Author: angela
Date: Wed Nov 27 13:39:25 2013
New Revision: 1546031

URL: http://svn.apache.org/r1546031
Log:
OAK-754 	: Pluggable Security Setup

Added:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeWorkspaceInitializer.java
      - copied, changed from r1545216, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeInitializer.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenConfiguration.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/CompositePrincipalConfiguration.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/PrincipalManagerImpl.java   (contents, props changed)
      - copied, changed from r1545216, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalManagerImpl.java
Removed:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalManagerImpl.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiSecurityProvider.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalConfigurationImpl.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/AuthorizableNodeName.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiSecurityProvider.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiSecurityProvider.java?rev=1546031&r1=1546030&r2=1546031&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiSecurityProvider.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/osgi/OsgiSecurityProvider.java Wed Nov 27 13:39:25 2013
@@ -16,21 +16,24 @@
  */
 package org.apache.jackrabbit.oak.osgi;
 
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
+import java.util.HashSet;
+import java.util.Set;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import com.google.common.collect.Maps;
-import org.apache.jackrabbit.oak.api.Root;
+import org.apache.felix.scr.annotations.Reference;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationBase;
 import org.apache.jackrabbit.oak.spi.security.ConfigurationParameters;
 import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
-import org.apache.jackrabbit.oak.spi.security.authentication.token.CompositeTokenProvider;
+import org.apache.jackrabbit.oak.spi.security.authentication.AuthenticationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.authentication.token.CompositeTokenConfiguration;
 import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenConfiguration;
-import org.apache.jackrabbit.oak.spi.security.authentication.token.TokenProvider;
+import org.apache.jackrabbit.oak.spi.security.authorization.AuthorizationConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.CompositePrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.privilege.PrivilegeConfiguration;
+import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 import org.osgi.framework.ServiceReference;
 
 /**
@@ -38,54 +41,28 @@ import org.osgi.framework.ServiceReferen
  */
 public class OsgiSecurityProvider extends AbstractServiceTracker<SecurityConfiguration> implements SecurityProvider {
 
+    @Reference(bind = "bindAuthorizationConfiguration")
+    private AuthorizationConfiguration authorizationConfiguration;
+
+    @Reference(bind = "bindAuthenticationConfiguration")
+    private AuthenticationConfiguration authenticationConfiguration;
+
+    @Reference(bind = "bindPrivilegeConfiguration")
+    private PrivilegeConfiguration privilegeConfiguration;
+
+    @Reference(bind = "bindUserConfiguration")
+    private UserConfiguration userConfiguration;
+
+    private CompositePrincipalConfiguration principalConfiguration = new CompositePrincipalConfiguration();
     private CompositeTokenConfiguration tokenConfiguration = new CompositeTokenConfiguration();
-    private Map<String, SecurityConfiguration> serviceMap = Maps.newHashMap();
+
     private ConfigurationParameters config;
 
     public OsgiSecurityProvider(@Nonnull ConfigurationParameters config) {
         super(SecurityConfiguration.class);
         this.config = config;
-        serviceMap.put(TokenConfiguration.NAME, tokenConfiguration);
-    }
-
-    //-------------------------------------------< ServiceTrackerCustomizer >---
-    @Override
-    public Object addingService(ServiceReference reference) {
-        Object service = super.addingService(reference);
-        if (service instanceof SecurityConfiguration) {
-            SecurityConfiguration sc = (SecurityConfiguration) service;
-
-            if (sc instanceof TokenConfiguration) {
-                tokenConfiguration.services.add((TokenConfiguration) sc);
-            } else {
-                synchronized (this) {
-                    serviceMap.put(sc.getName(), sc);
-                }
-            }
-
-            if (service instanceof ConfigurationBase) {
-                ((ConfigurationBase) service).setSecurityProvider(this);
-            }
-        }
-        return service;
     }
 
-    @Override
-    public void removedService(ServiceReference reference, Object service) {
-        super.removedService(reference, service);
-        if (service instanceof SecurityConfiguration) {
-            SecurityConfiguration sc = (SecurityConfiguration) service;
-            if (sc instanceof TokenConfiguration) {
-                tokenConfiguration.services.remove(sc);
-            } else {
-                synchronized (this) {
-                    serviceMap.remove(((SecurityConfiguration) service).getName());
-                }
-            }
-        }
-    }
-
-
     //---------------------------------------------------< SecurityProvider >---
     @Nonnull
     @Override
@@ -94,59 +71,91 @@ public class OsgiSecurityProvider extend
             return config;
         }
         ConfigurationParameters params = config.getConfigValue(name, ConfigurationParameters.EMPTY);
-        SecurityConfiguration sc = serviceMap.get(name);
-        if (sc != null) {
-            return ConfigurationParameters.of(params, sc.getParameters());
-        } else {
-            return params;
+        for (SecurityConfiguration sc : getConfigurations()) {
+            if (sc != null && sc.getName().equals(name)) {
+                return ConfigurationParameters.of(params, sc.getParameters());
+            }
         }
+        return params;
     }
 
     @Nonnull
     @Override
     public Iterable<? extends SecurityConfiguration> getConfigurations() {
-        return serviceMap.values();
+        Set<SecurityConfiguration> scs = new HashSet<SecurityConfiguration>();
+        scs.add(authenticationConfiguration);
+        scs.add(authorizationConfiguration);
+        scs.add(userConfiguration);
+        scs.add(principalConfiguration);
+        scs.add(privilegeConfiguration);
+        scs.add(tokenConfiguration);
+        return scs;
     }
 
     @Nonnull
     @Override
     public <T> T getConfiguration(@Nonnull Class<T> configClass) {
-        for (SecurityConfiguration sc : serviceMap.values()) {
-            if (configClass.isAssignableFrom(sc.getClass())) {
-                return (T) sc;
-            }
+        if (AuthenticationConfiguration.class == configClass) {
+            return (T) authenticationConfiguration;
+        } else if (AuthorizationConfiguration.class == configClass) {
+            return (T) authorizationConfiguration;
+        } else if (UserConfiguration.class == configClass) {
+            return (T) userConfiguration;
+        } else if (PrincipalConfiguration.class == configClass) {
+            return (T) principalConfiguration;
+        } else if (PrivilegeConfiguration.class == configClass) {
+            return (T) privilegeConfiguration;
+        } else if (TokenConfiguration.class == configClass) {
+            return (T) tokenConfiguration;
+        } else {
+            throw new IllegalArgumentException("Unsupported security configuration class " + configClass);
         }
-        throw new IllegalStateException("Unsupported configuration class " + configClass.getName());
     }
 
-    private final class CompositeTokenConfiguration extends ConfigurationBase implements TokenConfiguration {
-
-        private List<TokenConfiguration> services = new ArrayList<TokenConfiguration>();
-
-        @Nonnull
-        @Override
-        public TokenProvider getTokenProvider(Root root) {
-            List<TokenProvider> providers = new ArrayList<TokenProvider>();
-            for (TokenConfiguration tc : services) {
-                providers.add(tc.getTokenProvider(root));
-            }
-            return CompositeTokenProvider.newInstance(providers);
+    //-------------------------------------------< ServiceTrackerCustomizer >---
+    @Override
+    public Object addingService(ServiceReference reference) {
+        Object service = super.addingService(reference);
+        if (service instanceof TokenConfiguration) {
+            tokenConfiguration.addConfiguration((TokenConfiguration) service, this);
+        } else if (service instanceof PrincipalConfiguration) {
+            principalConfiguration.addConfiguration((PrincipalConfiguration) service, this);
         }
+        return service;
+    }
 
-        @Nonnull
-        @Override
-        public String getName() {
-            return TokenConfiguration.NAME;
+    @Override
+    public void removedService(ServiceReference reference, Object service) {
+        super.removedService(reference, service);
+        if (service instanceof TokenConfiguration) {
+            tokenConfiguration.removeConfiguration((TokenConfiguration) service);
+        } else if (service instanceof PrincipalConfiguration) {
+            principalConfiguration.removeConfiguration((PrincipalConfiguration) service);
         }
+    }
 
-        @Nonnull
-        @Override
-        public ConfigurationParameters getParameters() {
-            ConfigurationParameters[] params = new ConfigurationParameters[services.size()];
-            for (int i = 0; i < services.size(); i++) {
-                params[i] = services.get(i).getParameters();
-            }
-            return ConfigurationParameters.of(params);
+    //--------------------------------------------------------------------------
+    protected void bindAuthorizationConfiguration(@Nonnull ServiceReference reference) {
+        authorizationConfiguration = (AuthorizationConfiguration) initConfiguration(reference);
+    }
+
+    protected void bindAuthenticationConfiguration(@Nonnull ServiceReference reference) {
+        authenticationConfiguration = (AuthenticationConfiguration) initConfiguration(reference);
+    }
+
+    protected void bindUserConfiguration(@Nonnull ServiceReference reference) {
+        userConfiguration = (UserConfiguration) initConfiguration(reference);
+    }
+
+    protected void bindPrivilegeConfiguration(@Nonnull ServiceReference reference) {
+        privilegeConfiguration = (PrivilegeConfiguration) initConfiguration(reference);
+    }
+
+    private Object initConfiguration(@Nonnull ServiceReference reference) {
+        Object service = reference.getBundle().getBundleContext().getService(reference);
+        if (service instanceof ConfigurationBase) {
+            ((ConfigurationBase) service).setSecurityProvider(this);
         }
+        return service;
     }
-}
\ No newline at end of file
+}

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java?rev=1546031&r1=1546030&r2=1546031&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/authorization/permission/CompiledPermissionImpl.java Wed Nov 27 13:39:25 2013
@@ -58,7 +58,6 @@ import org.slf4j.LoggerFactory;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.Iterators;
 
-import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.collect.Iterators.concat;
 
 /**
@@ -385,7 +384,7 @@ final class CompiledPermissionImpl imple
         String versionablePath = null;
         Tree t = versionStoreTree;
         while (t.exists() && !t.isRoot() && !VersionConstants.VERSION_STORE_ROOT_NAMES.contains(t.getName())) {
-            String ntName = checkNotNull(TreeUtil.getPrimaryTypeName(t));
+            String ntName = TreeUtil.getPrimaryTypeName(t);
             if (VersionConstants.JCR_FROZENNODE.equals(t.getName()) && t != versionStoreTree) {
                 relPath = PathUtils.relativize(t.getPath(), versionStoreTree.getPath());
             } else if (JcrConstants.NT_VERSIONHISTORY.equals(ntName)) {

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalConfigurationImpl.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalConfigurationImpl.java?rev=1546031&r1=1546030&r2=1546031&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalConfigurationImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalConfigurationImpl.java Wed Nov 27 13:39:25 2013
@@ -27,6 +27,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.apache.jackrabbit.oak.spi.security.SecurityConfiguration;
 import org.apache.jackrabbit.oak.spi.security.SecurityProvider;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalConfiguration;
+import org.apache.jackrabbit.oak.spi.security.principal.PrincipalManagerImpl;
 import org.apache.jackrabbit.oak.spi.security.principal.PrincipalProvider;
 import org.apache.jackrabbit.oak.spi.security.user.UserConfiguration;
 

Copied: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeWorkspaceInitializer.java (from r1545216, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeInitializer.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeWorkspaceInitializer.java?p2=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeWorkspaceInitializer.java&p1=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeInitializer.java&r1=1545216&r2=1546031&rev=1546031&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeInitializer.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/lifecycle/CompositeWorkspaceInitializer.java Wed Nov 27 13:39:25 2013
@@ -20,33 +20,36 @@ package org.apache.jackrabbit.oak.spi.li
 
 import java.util.Arrays;
 import java.util.Collection;
-
 import javax.annotation.Nonnull;
 
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.query.QueryIndexProvider;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
-import org.apache.jackrabbit.oak.spi.state.NodeState;
 
 /**
  * Composite repository initializer that delegates the
- * {@link #initialize(NodeState)} call in sequence to all the
+ * {@link #initialize(org.apache.jackrabbit.oak.spi.state.NodeBuilder, String,
+ * org.apache.jackrabbit.oak.spi.query.QueryIndexProvider,
+ * org.apache.jackrabbit.oak.spi.commit.CommitHook)} calls in sequence to all the
  * component initializers.
  */
-public class CompositeInitializer implements RepositoryInitializer {
+public class CompositeWorkspaceInitializer implements WorkspaceInitializer {
 
-    private final Collection<RepositoryInitializer> initializers;
+    private final Collection<WorkspaceInitializer> initializers;
 
-    public CompositeInitializer(Collection<RepositoryInitializer> trackers) {
+    public CompositeWorkspaceInitializer(@Nonnull Collection<WorkspaceInitializer> trackers) {
         this.initializers = trackers;
     }
 
-    public CompositeInitializer(RepositoryInitializer... initializers) {
+    public CompositeWorkspaceInitializer(@Nonnull WorkspaceInitializer... initializers) {
         this.initializers = Arrays.asList(initializers);
     }
 
     @Override
-    public void initialize(@Nonnull NodeBuilder builder) {
-        for (RepositoryInitializer tracker : initializers) {
-            tracker.initialize(builder);
+    public void initialize(NodeBuilder builder, String workspaceName, QueryIndexProvider indexProvider, CommitHook commitHook) {
+        for (WorkspaceInitializer tracker : initializers) {
+            tracker.initialize(builder, workspaceName, indexProvider, commitHook);
         }
+
     }
 }

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java?rev=1546031&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/CompositeConfiguration.java Wed Nov 27 13:39:25 2013
@@ -0,0 +1,187 @@
+/*
+ * 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 org.apache.jackrabbit.oak.spi.security;
+
+import java.util.ArrayList;
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Function;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.api.PropertyState;
+import org.apache.jackrabbit.oak.api.Tree;
+import org.apache.jackrabbit.oak.spi.commit.CommitHook;
+import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
+import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
+import org.apache.jackrabbit.oak.spi.lifecycle.CompositeInitializer;
+import org.apache.jackrabbit.oak.spi.lifecycle.CompositeWorkspaceInitializer;
+import org.apache.jackrabbit.oak.spi.lifecycle.RepositoryInitializer;
+import org.apache.jackrabbit.oak.spi.lifecycle.WorkspaceInitializer;
+import org.apache.jackrabbit.oak.spi.xml.ProtectedItemImporter;
+import org.apache.jackrabbit.oak.util.TreeLocation;
+
+/**
+ * Abstract base implementation for {@link SecurityConfiguration}s that can
+ * combine different implementations.
+ */
+public abstract class CompositeConfiguration<T extends SecurityConfiguration> implements SecurityConfiguration {
+
+    private final List<T> configurations = new ArrayList<T>();
+
+    private final String name;
+
+    public CompositeConfiguration(String name) {
+        this.name = name;
+    }
+
+    public void addConfiguration(@Nonnull T configuration, @Nonnull SecurityProvider sp) {
+        configurations.add(configuration);
+        if (configuration instanceof ConfigurationBase) {
+            ((ConfigurationBase) configuration).setSecurityProvider(sp);
+        }
+    }
+
+    public void removeConfiguration(@Nonnull T configuration) {
+        configurations.remove(configuration);
+    }
+
+    public List<T> getConfigurations() {
+        return ImmutableList.copyOf(configurations);
+    }
+
+    //----------------------------------------------< SecurityConfiguration >---
+    @Nonnull
+    @Override
+    public String getName() {
+        return name;
+    }
+
+    @Nonnull
+    @Override
+    public ConfigurationParameters getParameters() {
+        ConfigurationParameters[] params = new ConfigurationParameters[configurations.size()];
+        for (int i = 0; i < configurations.size(); i++) {
+            params[i] = configurations.get(i).getParameters();
+        }
+        return ConfigurationParameters.of(params);
+    }
+
+    @Nonnull
+    @Override
+    public WorkspaceInitializer getWorkspaceInitializer() {
+        return new CompositeWorkspaceInitializer(Lists.transform(configurations, new Function<T, WorkspaceInitializer>() {
+            @Override
+            public WorkspaceInitializer apply(T securityConfiguration) {
+                return securityConfiguration.getWorkspaceInitializer();
+            }
+        }));
+    }
+
+    @Nonnull
+    @Override
+    public RepositoryInitializer getRepositoryInitializer() {
+        return new CompositeInitializer(Lists.transform(configurations, new Function<T, RepositoryInitializer>() {
+            @Override
+            public RepositoryInitializer apply(T securityConfiguration) {
+                return securityConfiguration.getRepositoryInitializer();
+            }
+        }));
+    }
+
+    @Nonnull
+    @Override
+    public List<? extends CommitHook> getCommitHooks(final String workspaceName) {
+        return ImmutableList.copyOf(Iterables.concat(Lists.transform(configurations, new Function<T, List<? extends CommitHook>>() {
+            @Override
+            public List<? extends CommitHook> apply(T securityConfiguration) {
+                return securityConfiguration.getCommitHooks(workspaceName);
+            }
+        })));
+    }
+
+    @Nonnull
+    @Override
+    public List<? extends ValidatorProvider> getValidators(final String workspaceName, final CommitInfo commitInfo) {
+        return ImmutableList.copyOf(Iterables.concat(Lists.transform(configurations, new Function<T, List<? extends ValidatorProvider>>() {
+            @Override
+            public List<? extends ValidatorProvider> apply(T securityConfiguration) {
+                return securityConfiguration.getValidators(workspaceName, commitInfo);
+            }
+        })));
+    }
+
+    @Nonnull
+    @Override
+    public List<ProtectedItemImporter> getProtectedItemImporters() {
+        return ImmutableList.copyOf(Iterables.concat(Lists.transform(configurations, new Function<T, List<? extends ProtectedItemImporter>>() {
+            @Override
+            public List<? extends ProtectedItemImporter> apply(T securityConfiguration) {
+                return securityConfiguration.getProtectedItemImporters();
+            }
+        })));
+    }
+
+    @Override
+    public Context getContext() {
+        return new Context() {
+
+            @Override
+            public boolean definesProperty(@Nonnull Tree parent, @Nonnull PropertyState property) {
+                for (SecurityConfiguration sc : configurations) {
+                    if (sc.getContext().definesProperty(parent, property)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            @Override
+            public boolean definesContextRoot(@Nonnull Tree tree) {
+                for (SecurityConfiguration sc : configurations) {
+                    if (sc.getContext().definesContextRoot(tree)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            @Override
+            public boolean definesTree(@Nonnull Tree tree) {
+                for (SecurityConfiguration sc : configurations) {
+                    if (sc.getContext().definesTree(tree)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+
+            @Override
+            public boolean definesLocation(@Nonnull TreeLocation location) {
+                for (SecurityConfiguration sc : configurations) {
+                    if (sc.getContext().definesLocation(location)) {
+                        return true;
+                    }
+                }
+                return false;
+            }
+        };
+    }
+}

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenConfiguration.java?rev=1546031&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenConfiguration.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/authentication/token/CompositeTokenConfiguration.java Wed Nov 27 13:39:25 2013
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.jackrabbit.oak.spi.security.authentication.token;
+
+import java.util.List;
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.spi.security.CompositeConfiguration;
+
+/**
+* {@link TokenConfiguration} that combines different token provider implementations.
+*/
+public final class CompositeTokenConfiguration extends CompositeConfiguration<TokenConfiguration> implements TokenConfiguration {
+
+    public CompositeTokenConfiguration() {
+        super(TokenConfiguration.NAME);
+    }
+
+    @Nonnull
+    @Override
+    public TokenProvider getTokenProvider(final Root root) {
+        List<TokenProvider> providers = Lists.transform(getConfigurations(), new Function<TokenConfiguration, TokenProvider>() {
+            @Override
+            public TokenProvider apply(TokenConfiguration tokenConfiguration) {
+                return tokenConfiguration.getTokenProvider(root);
+            }
+        });
+        return CompositeTokenProvider.newInstance(providers);
+    }
+}

Added: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/CompositePrincipalConfiguration.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/CompositePrincipalConfiguration.java?rev=1546031&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/CompositePrincipalConfiguration.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/CompositePrincipalConfiguration.java Wed Nov 27 13:39:25 2013
@@ -0,0 +1,54 @@
+/*
+ * 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 org.apache.jackrabbit.oak.spi.security.principal;
+
+import javax.annotation.Nonnull;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import org.apache.jackrabbit.api.security.principal.PrincipalManager;
+import org.apache.jackrabbit.oak.api.Root;
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.spi.security.CompositeConfiguration;
+
+/**
+ * {@link PrincipalConfiguration} that combines different principal provider
+ * implementations that share a common principal manager implementation.
+ */
+public final class CompositePrincipalConfiguration extends CompositeConfiguration<PrincipalConfiguration> implements PrincipalConfiguration {
+
+    public CompositePrincipalConfiguration() {
+        super(PrincipalConfiguration.NAME);
+    }
+
+    @Nonnull
+    @Override
+    public PrincipalManager getPrincipalManager(Root root, NamePathMapper namePathMapper) {
+        return new PrincipalManagerImpl(getPrincipalProvider(root, namePathMapper));
+    }
+
+    @Nonnull
+    @Override
+    public PrincipalProvider getPrincipalProvider(final Root root, final NamePathMapper namePathMapper) {
+        return new CompositePrincipalProvider(Lists.transform(getConfigurations(), new Function<PrincipalConfiguration, PrincipalProvider>() {
+            @Override
+            public PrincipalProvider apply(PrincipalConfiguration principalConfiguration) {
+                return principalConfiguration.getPrincipalProvider(root, namePathMapper);
+            }
+        }));
+    }
+}

Copied: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/PrincipalManagerImpl.java (from r1545216, jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalManagerImpl.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/PrincipalManagerImpl.java?p2=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/PrincipalManagerImpl.java&p1=jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalManagerImpl.java&r1=1545216&r2=1546031&rev=1546031&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/security/principal/PrincipalManagerImpl.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/PrincipalManagerImpl.java Wed Nov 27 13:39:25 2013
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.jackrabbit.oak.security.principal;
+package org.apache.jackrabbit.oak.spi.security.principal;
 
 import java.security.Principal;
 import javax.annotation.CheckForNull;
@@ -30,11 +30,11 @@ import org.apache.jackrabbit.oak.spi.sec
 /**
  * Default implementation of the {@code PrincipalManager} interface.
  */
-class PrincipalManagerImpl implements PrincipalManager {
+public class PrincipalManagerImpl implements PrincipalManager {
 
     private final PrincipalProvider principalProvider;
 
-    PrincipalManagerImpl(@Nonnull PrincipalProvider principalProvider) {
+    public PrincipalManagerImpl(@Nonnull PrincipalProvider principalProvider) {
         this.principalProvider = principalProvider;
     }
 

Propchange: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/principal/PrincipalManagerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/AuthorizableNodeName.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/AuthorizableNodeName.java?rev=1546031&r1=1546030&r2=1546031&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/AuthorizableNodeName.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/spi/security/user/AuthorizableNodeName.java Wed Nov 27 13:39:25 2013
@@ -16,6 +16,8 @@
  */
 package org.apache.jackrabbit.oak.spi.security.user;
 
+import javax.annotation.Nonnull;
+
 import org.apache.jackrabbit.util.Text;
 
 /**
@@ -39,7 +41,8 @@ public interface AuthorizableNodeName {
      * @param authorizableId The ID of the authorizable to be created.
      * @return A valid node name.
      */
-    String generateNodeName(String authorizableId);
+    @Nonnull
+    String generateNodeName(@Nonnull String authorizableId);
 
     /**
      * Default implementation of the {@code AuthorizableNodeName} interface
@@ -50,7 +53,8 @@ public interface AuthorizableNodeName {
     final class Default implements AuthorizableNodeName {
 
         @Override
-        public String generateNodeName(String authorizableId) {
+        @Nonnull
+        public String generateNodeName(@Nonnull String authorizableId) {
             return Text.escapeIllegalJcrChars(authorizableId);
         }
     }