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/22 00:09:33 UTC
[sling-org-apache-sling-auth-core] 01/01: SLING-9662 Use
PathToUriMappingService to pre-process path before authentication
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 64326aee30a3b904ffa21c8e67162df69575e31a
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..4b03116 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.0-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");
}
/**