You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by gh...@apache.org on 2020/09/27 01:54:23 UTC

[sling-org-apache-sling-auth-core] branch feature/SLING-9662-Introduce-SlingUri-Mapping-SPI-v3 updated (64326ae -> b4cc92c)

This is an automated email from the ASF dual-hosted git repository.

ghenzler pushed a change to branch feature/SLING-9662-Introduce-SlingUri-Mapping-SPI-v3
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-core.git.


 discard 64326ae  SLING-9662 Use PathToUriMappingService to pre-process path before authentication
     new b4cc92c  SLING-9662 Use PathToUriMappingService to pre-process path before authentication

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (64326ae)
            \
             N -- N -- N   refs/heads/feature/SLING-9662-Introduce-SlingUri-Mapping-SPI-v3 (b4cc92c)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)


[sling-org-apache-sling-auth-core] 01/01: SLING-9662 Use PathToUriMappingService to pre-process path before authentication

Posted by gh...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ghenzler pushed a commit to branch feature/SLING-9662-Introduce-SlingUri-Mapping-SPI-v3
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-core.git

commit b4cc92c962571daf6a77d9ec63c9f0609f2c1465
Author: georg.henzler <ge...@netcentric.biz>
AuthorDate: Mon Sep 21 10:44:56 2020 +0200

    SLING-9662 Use PathToUriMappingService to pre-process path before
    authentication
---
 pom.xml                                            |  2 +-
 .../sling/auth/core/AuthenticationSupport.java     |  8 +++
 .../sling/auth/core/impl/SlingAuthenticator.java   | 33 +++++-----
 .../org/apache/sling/auth/core/package-info.java   |  4 +-
 .../auth/core/impl/SlingAuthenticatorTest.java     | 77 ++++++++++------------
 5 files changed, 64 insertions(+), 60 deletions(-)

diff --git a/pom.xml b/pom.xml
index fb78d39..bf74525 100644
--- a/pom.xml
+++ b/pom.xml
@@ -71,7 +71,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
-            <version>2.20.0</version>
+            <version>2.23.1-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/src/main/java/org/apache/sling/auth/core/AuthenticationSupport.java b/src/main/java/org/apache/sling/auth/core/AuthenticationSupport.java
index 7257110..0f2dd4d 100644
--- a/src/main/java/org/apache/sling/auth/core/AuthenticationSupport.java
+++ b/src/main/java/org/apache/sling/auth/core/AuthenticationSupport.java
@@ -85,6 +85,14 @@ public interface AuthenticationSupport {
     static final String REQUEST_ATTRIBUTE_RESOLVER = "org.apache.sling.auth.core.ResourceResolver";
 
     /**
+     * The name of the request attribute set by the {@link #handleSecurity(HttpServletRequest, HttpServletResponse)} method for the request
+     * URI that was resolved already.
+     * <p>
+     * The request attribute is set to a Sling <code>SlingUri</code> as provided by PathToUriMappingService.resolve().
+     */
+    static final String REQUEST_ATTRIBUTE_URI = "org.apache.sling.auth.core.SlingUri";
+
+    /**
      * The name of the request parameter indicating where to redirect to after
      * successful authentication (and optional impersonation). This parameter is
      * respected if either anonymous authentication or regular authentication
diff --git a/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java b/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
index 6e203cc..0f2054a 100644
--- a/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
+++ b/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
@@ -50,6 +50,8 @@ import org.apache.sling.api.auth.NoAuthenticationHandlerException;
 import org.apache.sling.api.resource.LoginException;
 import org.apache.sling.api.resource.ResourceResolver;
 import org.apache.sling.api.resource.ResourceResolverFactory;
+import org.apache.sling.api.resource.mapping.PathToUriMappingService;
+import org.apache.sling.api.uri.SlingUri;
 import org.apache.sling.auth.core.AuthConstants;
 import org.apache.sling.auth.core.AuthUtil;
 import org.apache.sling.auth.core.AuthenticationSupport;
@@ -260,6 +262,9 @@ public class SlingAuthenticator implements Authenticator,
     @Reference
     private ResourceResolverFactory resourceResolverFactory;
 
+    @Reference
+    private PathToUriMappingService pathToUriMappingService;
+
     private PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authHandlerCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
 
     // package protected for access in inner class ...
@@ -506,7 +511,7 @@ public class SlingAuthenticator implements Authenticator,
 
     private boolean doHandleSecurity(HttpServletRequest request, HttpServletResponse response) {
 
-        // 0. Check for request attribute; set if not present
+        // 0 Check for request attribute; set if not present
         Object authUriSufficesAttr = request
                 .getAttribute(AuthConstants.ATTR_REQUEST_AUTH_URI_SUFFIX);
         if (authUriSufficesAttr == null && authUriSuffices != null) {
@@ -747,22 +752,18 @@ public class SlingAuthenticator implements Authenticator,
      * @return The path
      */
     private String getPath(final HttpServletRequest request) {
-        final StringBuilder sb = new StringBuilder();
-        if (request.getServletPath() != null) {
-            sb.append(request.getServletPath());
-        }
-        if (request.getPathInfo() != null) {
-            sb.append(request.getPathInfo());
-        }
-        String path = sb.toString();
-        // Get the path used to select the authenticator, if the SlingServlet
-        // itself has been requested without any more info, this will be empty
-        // and we assume the root (SLING-722)
-        if (path.length() == 0) {
-            path = "/";
-        }
 
-        return path;
+        // this method is safely called from all three public entry points (that is handleSecurity(), login(), logout())
+        // for all execution paths
+        // therefore Sling engine may rely on AuthenticationSupport.REQUEST_ATTRIBUTE_URI
+
+        SlingUri slingUri = (SlingUri) request.getAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_URI);
+        if (slingUri == null) {
+            slingUri = pathToUriMappingService.resolve(request, null).getUri();
+            request.setAttribute(AuthenticationSupport.REQUEST_ATTRIBUTE_URI, slingUri);
+        }
+        
+        return slingUri.getPath();
     }
 
     private AuthenticationInfo getAuthenticationInfo(HttpServletRequest request, HttpServletResponse response) {
diff --git a/src/main/java/org/apache/sling/auth/core/package-info.java b/src/main/java/org/apache/sling/auth/core/package-info.java
index 66dee4f..f8d608e 100755
--- a/src/main/java/org/apache/sling/auth/core/package-info.java
+++ b/src/main/java/org/apache/sling/auth/core/package-info.java
@@ -22,9 +22,9 @@
  * of utility functions in the {@link org.apache.sling.auth.core.AuthUtil}
  * class.
  *
- * @version 1.4.0
+ * @version 1.5.0
  */
-@org.osgi.annotation.versioning.Version("1.4.0")
+@org.osgi.annotation.versioning.Version("1.5.0")
 package org.apache.sling.auth.core;
 
 
diff --git a/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java b/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java
index d3654cf..97cfd51 100644
--- a/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java
+++ b/src/test/java/org/apache/sling/auth/core/impl/SlingAuthenticatorTest.java
@@ -18,22 +18,49 @@
  */
 package org.apache.sling.auth.core.impl;
 
+import static org.mockito.Mockito.when;
+
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.sling.api.resource.mapping.PathToUriMappingService;
+import org.apache.sling.api.uri.SlingUriBuilder;
 import org.apache.sling.auth.core.spi.AuthenticationFeedbackHandler;
 import org.apache.sling.auth.core.spi.AuthenticationInfo;
 import org.junit.Assert;
+import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.InjectMocks;
+import org.mockito.Mock;
 import org.mockito.Mockito;
+import org.mockito.junit.MockitoJUnitRunner;
 
 import junitx.util.PrivateAccessor;
 
+@RunWith(MockitoJUnitRunner.class)
 public class SlingAuthenticatorTest {
 
+    @InjectMocks
+    SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
+
+    @Mock
+    PathToUriMappingService pathToUriMappingService;
+
+    @Mock
+    HttpServletRequest request;
+
+    @Mock
+    PathToUriMappingService.Result resolveResult;
+
+    @Before
+    public void setup() {
+        when(pathToUriMappingService.resolve(request, null)).thenReturn(resolveResult);
+    }
+
     @Test
     public void test_quoteCookieValue() throws UnsupportedEncodingException {
 
@@ -82,14 +109,13 @@ public class SlingAuthenticatorTest {
     //SLING-4864
     @Test
     public void  test_isAnonAllowed() throws Throwable {
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
-        PathBasedHolderCache<AuthenticationRequirementHolder> authRequiredCache = new PathBasedHolderCache<AuthenticationRequirementHolder>();
+        when(resolveResult.getUri()).thenReturn(SlingUriBuilder.parse("/", null).build());
 
+        PathBasedHolderCache<AuthenticationRequirementHolder> authRequiredCache = new PathBasedHolderCache<AuthenticationRequirementHolder>();
         authRequiredCache.addHolder(new AuthenticationRequirementHolder("/", false, null));
 
         PrivateAccessor.setField(slingAuthenticator, "authRequiredCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         Mockito.when(request.getServerName()).thenReturn("localhost");
         Mockito.when(request.getServerPort()).thenReturn(80);
         Mockito.when(request.getScheme()).thenReturn("http");
@@ -109,13 +135,10 @@ public class SlingAuthenticatorTest {
         final String PROTECTED_PATH = "/content/en/test";
         final String REQUEST_CHILD_NODE = "/content/en/test/childnodetest";
 
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
-
         PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authRequiredCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE, PROTECTED_PATH));
 
         PrivateAccessor.setField(slingAuthenticator, "authHandlerCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         buildExpectationsForRequest(request, REQUEST_CHILD_NODE);
 
         AuthenticationInfo authInfo = (AuthenticationInfo) PrivateAccessor.invoke(slingAuthenticator, "getAuthenticationInfo",
@@ -136,13 +159,10 @@ public class SlingAuthenticatorTest {
         final String PROTECTED_PATH = "/content/en/test";
         final String REQUEST_CHILD_NODE = "/content/en/test";
 
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
-
         PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authRequiredCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE, PROTECTED_PATH));
 
         PrivateAccessor.setField(slingAuthenticator, "authHandlerCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         buildExpectationsForRequest(request, REQUEST_CHILD_NODE);
 
         AuthenticationInfo authInfo = (AuthenticationInfo) PrivateAccessor.invoke(slingAuthenticator, "getAuthenticationInfo",
@@ -163,13 +183,10 @@ public class SlingAuthenticatorTest {
         final String PROTECTED_PATH = "/content/en/test";
         final String REQUEST_CHILD_NODE = "/content/en/test/";
 
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
-
         PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authRequiredCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE, PROTECTED_PATH));
 
         PrivateAccessor.setField(slingAuthenticator, "authHandlerCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         buildExpectationsForRequest(request, REQUEST_CHILD_NODE);
 
         AuthenticationInfo authInfo = (AuthenticationInfo) PrivateAccessor.invoke(slingAuthenticator, "getAuthenticationInfo",
@@ -190,13 +207,10 @@ public class SlingAuthenticatorTest {
         final String PROTECTED_PATH = "/content/en/test";
         final String REQUEST_CHILD_NODE = "/content/en/test.html";
 
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
-
         PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authRequiredCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE, PROTECTED_PATH));
 
         PrivateAccessor.setField(slingAuthenticator, "authHandlerCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         buildExpectationsForRequest(request, REQUEST_CHILD_NODE);
 
         AuthenticationInfo authInfo = (AuthenticationInfo) PrivateAccessor.invoke(slingAuthenticator, "getAuthenticationInfo",
@@ -213,13 +227,10 @@ public class SlingAuthenticatorTest {
         final String PROTECTED_PATH = "/";
         final String REQUEST_CHILD_NODE = "/content/en/test";
 
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
-
         PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authRequiredCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE, PROTECTED_PATH));
 
         PrivateAccessor.setField(slingAuthenticator, "authHandlerCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         buildExpectationsForRequest(request, REQUEST_CHILD_NODE);
 
         AuthenticationInfo authInfo = (AuthenticationInfo) PrivateAccessor.invoke(slingAuthenticator, "getAuthenticationInfo",
@@ -238,14 +249,11 @@ public class SlingAuthenticatorTest {
         final String PROTECTED_PATH_LONGER = "/resource1.test2";
         final String REQUEST_CHILD_NODE = "/resource1.test2";
 
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
-
         PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authRequiredCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE, PROTECTED_PATH));
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE_LONGER, PROTECTED_PATH_LONGER));
 
         PrivateAccessor.setField(slingAuthenticator, "authHandlerCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         buildExpectationsForRequest(request, REQUEST_CHILD_NODE);
 
         AuthenticationInfo authInfo = (AuthenticationInfo) PrivateAccessor.invoke(slingAuthenticator, "getAuthenticationInfo",
@@ -279,19 +287,16 @@ public class SlingAuthenticatorTest {
         final String PROTECTED_PATH = "/content/en/test";
         final String REQUEST_NOT_PROTECTED_PATH = "/content/en/test2";
 
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
-
         PathBasedHolderCache<AbstractAuthenticationHandlerHolder> authRequiredCache = new PathBasedHolderCache<AbstractAuthenticationHandlerHolder>();
         authRequiredCache.addHolder(buildAuthHolderForAuthTypeAndPath(AUTH_TYPE, PROTECTED_PATH));
 
         PrivateAccessor.setField(slingAuthenticator, "authHandlerCache", authRequiredCache);
-        final HttpServletRequest request = Mockito.mock(HttpServletRequest.class);
         buildExpectationsForRequest(request, REQUEST_NOT_PROTECTED_PATH);
 
         AuthenticationInfo authInfo = (AuthenticationInfo) PrivateAccessor.invoke(slingAuthenticator, "getAuthenticationInfo",
                 new Class[]{HttpServletRequest.class, HttpServletResponse.class}, new Object[]{request, Mockito.mock(HttpServletResponse.class)});
         /**
-         * The AUTH TYPE defined aboved should not be used for the path /test2.
+         * The AUTH TYPE defined above should not be used for the path /test2.
          */
         Assert.assertFalse(AUTH_TYPE.equals(authInfo.getAuthType()));
     }
@@ -300,7 +305,6 @@ public class SlingAuthenticatorTest {
     public void test_childNodeAuthenticationHandlerPath() throws Throwable {
         final String requestPath = "/content/test/test2";
         final String handlerPath = "/content/test";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -309,7 +313,6 @@ public class SlingAuthenticatorTest {
     public void test_siblingNodeAuthenticationHandlerPath() throws Throwable {
         final String requestPath = "/content/test2.html/en/2016/09/19/test.html";
         final String handlerPath = "/content/test";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertFalse( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -318,7 +321,6 @@ public class SlingAuthenticatorTest {
     public void test_actualNodeAuthenticationHandlerPath() throws Throwable {
         final String requestPath = "/content/test";
         final String handlerPath = "/content/test";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -327,7 +329,6 @@ public class SlingAuthenticatorTest {
     public void test_rootNodeAuthenticationHandlerPath() throws Throwable {
         final String requestPath = "/content/test";
         final String handlerPath = "/";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -336,7 +337,6 @@ public class SlingAuthenticatorTest {
     public void test_requestPathSelectorsAreTakenInConsideration() throws Throwable {
         final String requestPath = "/content/test.selector1.selector2.html/en/2016/test.html";
         final String handlerPath = "/content/test";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -345,7 +345,6 @@ public class SlingAuthenticatorTest {
     public void test_requestPathSelectorsSiblingAreTakenInConsideration() throws Throwable {
         final String requestPath = "/content/test.selector1.selector2.html/en/2016/09/19/test.html";
         final String handlerPath = "/content/test2";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertFalse( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -354,7 +353,6 @@ public class SlingAuthenticatorTest {
     public void test_requestPathBackSlash() throws Throwable {
         final String requestPath = "/page1\\somesubepage";
         final String handlerPath = "/page";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertFalse( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -363,7 +361,6 @@ public class SlingAuthenticatorTest {
     public void test_emptyNodeAuthenticationHandlerPath() throws Throwable {
         final String requestPath = "/content/test";
         final String handlerPath = "";
-        SlingAuthenticator slingAuthenticator = new SlingAuthenticator();
 
         Assert.assertTrue( (boolean)PrivateAccessor.invoke(slingAuthenticator, "isNodeRequiresAuthHandler", new Class[] {String.class, String.class}, new Object[] {requestPath, handlerPath}));
     }
@@ -376,14 +373,12 @@ public class SlingAuthenticatorTest {
      * @param request http request
      * @param requestPath request path
      */
-    private void buildExpectationsForRequest(final HttpServletRequest request,
-            final String requestPath) {
-        {
-            Mockito.when(request.getServletPath()).thenReturn(requestPath);
-            Mockito.when(request.getServerName()).thenReturn("localhost");
-            Mockito.when(request.getServerPort()).thenReturn(80);
-            Mockito.when(request.getScheme()).thenReturn("http");
-        }
+    private void buildExpectationsForRequest(final HttpServletRequest request, final String requestPath) {
+        // path is not taken directly from request but from PathToUriMappingService
+        when(resolveResult.getUri()).thenReturn(SlingUriBuilder.parse(requestPath, null).build());
+        when(request.getServerName()).thenReturn("localhost");
+        when(request.getServerPort()).thenReturn(80);
+        when(request.getScheme()).thenReturn("http");
     }
 
     /**