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 2015/08/11 09:41:07 UTC

svn commit: r1695223 [2/2] - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/nodetype/ oak-core/src/main/java/org/apache/jackrabbit/oak/security/user/ oak-core/src/main/resources/org/apache/jackrabbit/oak/plugins/node...

Added: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/principal/principalprovider.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/principal/principalprovider.md?rev=1695223&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/principal/principalprovider.md (added)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/principal/principalprovider.md Tue Aug 11 07:41:07 2015
@@ -0,0 +1,61 @@
+<!--
+   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.
+-->
+
+Implementations of the PrincipalProvider Interface
+--------------------------------------------------------------------------------
+
+Oak contains by default the following implementations of the `PrincipalProvider`
+interface:
+
+### org.apache.jackrabbit.oak.security.principal.PrincipalProviderImpl
+
+This is the default implementation of the `PrincipalProvider`, which makes use
+of the fact that `Authorizable`s as defined by the Jackrabbit user management
+API are always paired with a `Principal`.
+
+The implementation is not tied to a particular user management implementation
+and doesn't need to be rewritten if the security setup would be configured with
+different implementation of `UserConfiguration`.
+
+### org.apache.jackrabbit.oak.security.user.UserPrincipalProvider
+
+The introduction of the optional `UserConfiguration.getUserPrincipalProvider`
+extension allows for an optimized variant of the default principal provider, which
+is reading principal information from user and group accounts always paired with
+a `Principal` instance.
+
+This extension allows for a provider based implementation details of the user
+management implementation it is associated with, offering the ability to optimize
+the principal lookup without having to use regular Jackrabbit user management
+API calls and the associated overhead in terms of user/group object creation.
+
+While the implementation is located along with the user management implementation
+present in Oak this provider implementation should not be considered being
+part of the user management API implementation.
+
+Another benefit of this optimized implementation is the ability to specifically
+cache the results of the principal resolution in order to improve login performance.
+See section [Caching Results of Principal Resolution](cache.html) for further details.
+
+### org.apache.jackrabbit.oak.spi.security.principal.CompositePrincipalProvider
+
+This implementation is a simple wrapper implementation that combines different
+principals from different source providers. It is used in
+`CompositePrincipalConfiguration` held by the default `SecurityProvider` to
+collect all configured/plugged principal configurations i.e. the various
+implementations of principal management.
+

Modified: jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user.md
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user.md?rev=1695223&r1=1695222&r2=1695223&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user.md (original)
+++ jackrabbit/oak/trunk/oak-doc/src/site/markdown/security/user.md Tue Aug 11 07:41:07 2015
@@ -295,14 +295,20 @@ as of OAK 1.0:
 | `PARAM_PASSWORD_MAX_AGE`            | int     | 0                                            |
 | `PARAM_PASSWORD_INITIAL_CHANGE`     | boolean | false                                        |
 | `PARAM_PASSWORD_HISTORY_SIZE`       | int (upper limit: 1000) | 0                            |
+| `PARAM_CACHE_EXPIRATION`            | long    | 0                                            |
 | | | |
 
 The following configuration parameters present with the default implementation in Jackrabbit 2.x are no longer supported and will be ignored:
 
-* 'compatibleJR16'
-* 'autoExpandTree'
-* 'autoExpandSize'
-* 'groupMembershipSplitSize'
+* `compatibleJR16`
+* `autoExpandTree`
+* `autoExpandSize`
+* `groupMembershipSplitSize`
+
+The optional `cacheExpiration` configuration option listed above is discussed in
+detail in section [Caching Results of Principal Resolution](principal/cache.html).
+It is not related to user management s.str. but affects the implementation
+specific `PrincipalProvider` implementation exposed by `UserConfiguration.getUserPrincipalProvider`.
 
 ### Pluggability
 

Copied: jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportCacheTest.java (from r1692462, jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportHistoryTest.java)
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportCacheTest.java?p2=jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportCacheTest.java&p1=jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportHistoryTest.java&r1=1692462&r2=1695223&rev=1695223&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportHistoryTest.java (original)
+++ jackrabbit/oak/trunk/oak-jcr/src/test/java/org/apache/jackrabbit/oak/jcr/security/user/UserImportCacheTest.java Tue Aug 11 07:41:07 2015
@@ -23,6 +23,7 @@ import org.apache.jackrabbit.oak.spi.sec
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 /**
@@ -30,7 +31,7 @@ import static org.junit.Assert.assertTru
  * and pw-history content: test that the history is imported irrespective of the
  * configuration.
  */
-public class UserImportHistoryTest extends AbstractImportTest {
+public class UserImportCacheTest extends AbstractImportTest {
 
     @Override
     protected String getTargetPath() {
@@ -43,10 +44,10 @@ public class UserImportHistoryTest exten
     }
 
     /**
-     * @since Oak 1.3.3
+     * @since Oak 1.3.4
      */
     @Test
-    public void testImportUserWithPwdHistory() throws Exception {
+    public void testImportUserWithCache() throws Exception {
         // import user
         String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
                 "<sv:node sv:name=\"y\" xmlns:mix=\"http://www.jcp.org/jcr/mix/1.0\" xmlns:nt=\"http://www.jcp.org/jcr/nt/1.0\" xmlns:fn_old=\"http://www.w3.org/2004/10/xpath-functions\" xmlns:fn=\"http://www.w3.org/2005/xpath-functions\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xmlns:sv=\"http://www.jcp.org/jcr/sv/1.0\" xmlns:rep=\"internal\" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\">" +
@@ -62,24 +63,24 @@ public class UserImportHistoryTest exten
                 "   <sv:property sv:name=\"rep:principalName\" sv:type=\"String\">" +
                 "      <sv:value>yPrincipal</sv:value>" +
                 "   </sv:property>" +
-                "   <sv:node sv:name=\"" + UserConstants.REP_PWD + "\">" +
+                "   <sv:node sv:name=\"rep:cache\">" +
                 "      <sv:property sv:name=\"jcr:primaryType\" sv:type=\"Name\">" +
-                "         <sv:value>" + UserConstants.NT_REP_PASSWORD + "</sv:value>" +
+                "         <sv:value>rep:Cache</sv:value>" +
                 "      </sv:property>" +
-                "      <sv:property sv:name=\"" + UserConstants.REP_PWD_HISTORY + "\" sv:type=\"String\" sv:multiple=\"true\">" +
-                "         <sv:value>{sha1}8efd86fb78a56a5145ed7739dcb00c78581c5375</sv:value>" +
+                "      <sv:property sv:name=\"rep:expiration\" sv:type=\"Long\">" +
+                "         <sv:value>123456789</sv:value>" +
+                "      </sv:property>" +
+                "      <sv:property sv:name=\"rep:groupPrincipalNames\" sv:type=\"String\" sv:multiple=\"true\">" +
+                "         <sv:value>\"testGroup\"</sv:value>" +
                 "      </sv:property>" +
                 "   </sv:node>" +
                 "</sv:node>";
 
         doImport(USERPATH, xml);
+        getImportSession().save();
 
         Authorizable authorizable = getUserManager().getAuthorizable("y");
         Node userNode = getImportSession().getNode(authorizable.getPath());
-        assertTrue(userNode.hasNode(UserConstants.REP_PWD));
-
-        Node pwdNode = userNode.getNode(UserConstants.REP_PWD);
-        assertTrue(pwdNode.hasProperty(UserConstants.REP_PWD_HISTORY));
-        assertEquals("{sha1}8efd86fb78a56a5145ed7739dcb00c78581c5375", pwdNode.getProperty(UserConstants.REP_PWD_HISTORY).getString());
+        assertFalse(userNode.hasNode("rep:cache"));
     }
 }

Modified: jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh?rev=1695223&r1=1695222&r2=1695223&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh (original)
+++ jackrabbit/oak/trunk/oak-run/run_concurrent_login.sh Tue Aug 11 07:41:07 2015
@@ -16,10 +16,11 @@
 # limitations under the License.
 #
 TITLE=LoginTest
-BENCH="LoginWithMembersTest LoginWithMembershipTest" # LoginTest LoginLogoutTest LoginGetRootLogoutTest"
+BENCH="LoginWithMembershipTest" #LoginWithMembersTest LoginWithMembershipTest LoginTest LoginLogoutTest LoginGetRootLogoutTest"
 USER="user" # admin anonymous"
 USE_TOKEN=false # true
 HASH_ITERATIONS="-1"
+EXPIRATION="200000"
 NO_GROUPS="1 10 100 1000"
 USE_NESTED_GROUPS=true # false
 RUNTIME=5
@@ -38,6 +39,7 @@ echo "Profiling: $PROFILE" >> $LOG
 echo "User: $USER" >> $LOG
 echo "Run with Token: $USE_TOKEN" >> $LOG
 echo "Hash Iterations: $HASH_ITERATIONS" >> $LOG
+echo "Cache Expiration: $EXPIRATION" >> $LOG
 echo "Number of Groups: $NO_GROUPS" >> $LOG
 echo "Use Nested Groups: $USE_NESTED_GROUPS" >> $LOG
 
@@ -53,7 +55,8 @@ for bm in $BENCH
             echo "Executing benchmarks as user: $USER with $noGroups groups (nested = $USE_NESTED_GROUPS) on $fix" | tee -a $LOG
         echo "-----------------------------------------------------------" | tee -a $LOG
             rm -rf target/Jackrabbit-* target/Oak-Tar-*
-            cmd="java -Xmx2048m -Dprofile=$PROFILE -Druntime=$RUNTIME -Dwarmup=10 -jar target/oak-run-*-SNAPSHOT.jar benchmark --noIterations $HASH_ITERATIONS --runWithToken $USE_TOKEN --numberOfGroups $noGroups --nestedGroups $USE_NESTED_GROUPS --csvFile $LOG --concurrency $THREADS --runAsUser $USER --report false $bm $fix"
+            # cmd="java -Xmx2048m -Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005 -Dprofile=$PROFILE -Druntime=$RUNTIME -Dwarmup=10 -jar target/oak-run-*-SNAPSHOT.jar benchmark --noIterations $HASH_ITERATIONS --runWithToken $USE_TOKEN --expiration $EXPIRATION --numberOfGroups $noGroups --nestedGroups $USE_NESTED_GROUPS --csvFile $LOG --concurrency $THREADS --runAsUser $USER --report false $bm $fix"
+            cmd="java -Xmx2048m -Dprofile=$PROFILE -Druntime=$RUNTIME -Dwarmup=10 -jar target/oak-run-*-SNAPSHOT.jar benchmark --noIterations $HASH_ITERATIONS --runWithToken $USE_TOKEN --expiration $EXPIRATION --numberOfGroups $noGroups --nestedGroups $USE_NESTED_GROUPS --csvFile $LOG --concurrency $THREADS --runAsUser $USER --report false $bm $fix"
             echo $cmd
             $cmd
         done

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractLoginTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractLoginTest.java?rev=1695223&r1=1695222&r2=1695223&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractLoginTest.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/AbstractLoginTest.java Tue Aug 11 07:41:07 2015
@@ -16,8 +16,6 @@
  */
 package org.apache.jackrabbit.oak.benchmark;
 
-import java.util.Collections;
-import java.util.Map;
 import javax.jcr.Credentials;
 import javax.jcr.GuestCredentials;
 import javax.jcr.Repository;
@@ -27,7 +25,6 @@ import javax.jcr.SimpleCredentials;
 import javax.jcr.security.Privilege;
 import javax.security.auth.login.Configuration;
 
-import com.google.common.collect.ImmutableMap;
 import org.apache.jackrabbit.api.JackrabbitSession;
 import org.apache.jackrabbit.api.security.authentication.token.TokenCredentials;
 import org.apache.jackrabbit.api.security.user.Authorizable;
@@ -54,20 +51,27 @@ abstract class AbstractLoginTest extends
     public final static int COUNT = 1000;
     public final static String USER = "user";
     public final static int DEFAULT_ITERATIONS = -1;
+    public final static long NO_CACHE = -1;
 
     private String runAsUser;
     private boolean runWithToken;
     private int noIterations;
+    private long expiration;
 
     public AbstractLoginTest() {
         this("admin", false, DEFAULT_ITERATIONS);
     }
 
     public AbstractLoginTest(String runAsUser, boolean runWithToken, int noIterations) {
+        this(runAsUser, runWithToken, noIterations, NO_CACHE);
+    }
+
+    public AbstractLoginTest(String runAsUser, boolean runWithToken, int noIterations, long expiration) {
         super();
         this.runAsUser = runAsUser;
         this.runWithToken = runWithToken;
         this.noIterations = noIterations;
+        this.expiration = expiration;
     }
 
     @Override
@@ -102,15 +106,23 @@ abstract class AbstractLoginTest extends
 
     @Override
     protected Repository[] createRepository(RepositoryFixture fixture) throws Exception {
-        if (noIterations != -1) {
+        if (noIterations != -1 || expiration > 0) {
             if (fixture instanceof OakRepositoryFixture) {
-                final String configName = (runWithToken) ? TokenConfiguration.NAME : UserConfiguration.NAME;
                 return ((OakRepositoryFixture) fixture).setUpCluster(1, new JcrCreator() {
                     @Override
                     public Jcr customize(Oak oak) {
-                        Map<String, Integer> map = Collections.singletonMap(UserConstants.PARAM_PASSWORD_HASH_ITERATIONS, noIterations);
-                        ConfigurationParameters conf = ConfigurationParameters.of(map);
-                        SecurityProvider sp = new SecurityProviderImpl(ConfigurationParameters.of(ImmutableMap.of(configName, conf)));
+                        ConfigurationParameters conf;
+                        ConfigurationParameters iterations = ConfigurationParameters.of(UserConstants.PARAM_PASSWORD_HASH_ITERATIONS, noIterations);
+                        ConfigurationParameters cache = ConfigurationParameters.of("cacheExpiration", expiration);
+                        if (runWithToken) {
+                            conf = ConfigurationParameters.of(
+                                    TokenConfiguration.NAME, iterations,
+                                    UserConfiguration.NAME, cache);
+                        } else {
+                            conf = ConfigurationParameters.of(
+                                    UserConfiguration.NAME, ConfigurationParameters.of(iterations, cache));
+                        }
+                        SecurityProvider sp = new SecurityProviderImpl(conf);
                         return new Jcr(oak).with(sp);
                     }
                 });

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java?rev=1695223&r1=1695222&r2=1695223&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/BenchmarkRunner.java Tue Aug 11 07:41:07 2015
@@ -92,6 +92,8 @@ public class BenchmarkRunner {
                 .withOptionalArg().ofType(Boolean.class).defaultsTo(Boolean.FALSE);
         OptionSpec<Integer> noIterations = parser.accepts("noIterations", "Change default 'passwordHashIterations' parameter.")
                 .withOptionalArg().ofType(Integer.class).defaultsTo(AbstractLoginTest.DEFAULT_ITERATIONS);
+        OptionSpec<Long> expiration = parser.accepts("expiration", "Expiration time (e.g. principal cache.")
+                        .withOptionalArg().ofType(Long.class).defaultsTo(AbstractLoginTest.NO_CACHE);
         OptionSpec<Integer> numberOfGroups = parser.accepts("numberOfGroups", "Number of groups to create.")
                         .withOptionalArg().ofType(Integer.class).defaultsTo(LoginWithMembershipTest.NUMBER_OF_GROUPS_DEFAULT);
         OptionSpec<Boolean> nestedGroups = parser.accepts("nestedGroups", "Use nested groups.")
@@ -182,11 +184,13 @@ public class BenchmarkRunner {
                     runWithToken.value(options),
                     noIterations.value(options),
                     numberOfGroups.value(options),
-                    nestedGroups.value(options)),
+                    nestedGroups.value(options),
+                    expiration.value(options)),
             new LoginWithMembersTest(
                     runWithToken.value(options),
                     noIterations.value(options),
-                    numberOfGroups.value(options)),
+                    numberOfGroups.value(options),
+                    expiration.value(options)),
             new NamespaceTest(),
             new NamespaceRegistryTest(),
             new ReadPropertyTest(),

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembersTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembersTest.java?rev=1695223&r1=1695222&r2=1695223&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembersTest.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembersTest.java Tue Aug 11 07:41:07 2015
@@ -39,8 +39,8 @@ public class LoginWithMembersTest extend
 
     private final int numberOfMembers;
 
-    public LoginWithMembersTest(boolean runWithToken, int noIterations, int numberOfMembers) {
-        super(USER, runWithToken, noIterations);
+    public LoginWithMembersTest(boolean runWithToken, int noIterations, int numberOfMembers, long expiration) {
+        super(USER, runWithToken, noIterations, expiration);
 
         this.numberOfMembers = numberOfMembers;
     }

Modified: jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembershipTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembershipTest.java?rev=1695223&r1=1695222&r2=1695223&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembershipTest.java (original)
+++ jackrabbit/oak/trunk/oak-run/src/main/java/org/apache/jackrabbit/oak/benchmark/LoginWithMembershipTest.java Tue Aug 11 07:41:07 2015
@@ -42,8 +42,8 @@ public class LoginWithMembershipTest ext
     private final int numberOfGroups;
     private final boolean nestedGroups;
 
-    public LoginWithMembershipTest(boolean runWithToken, int noIterations, int numberOfGroups, boolean nestedGroups) {
-        super(USER, runWithToken, noIterations);
+    public LoginWithMembershipTest(boolean runWithToken, int noIterations, int numberOfGroups, boolean nestedGroups, long expiration) {
+        super(USER, runWithToken, noIterations, expiration);
 
         this.numberOfGroups = numberOfGroups;
         this.nestedGroups = nestedGroups;