You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2011/11/07 15:01:01 UTC
svn commit: r1198738 - in /sling/trunk/bundles/auth/core/src/main:
java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
resources/OSGI-INF/metatype/metatype.properties
Author: fmeschbe
Date: Mon Nov 7 14:01:01 2011
New Revision: 1198738
URL: http://svn.apache.org/viewvc?rev=1198738&view=rev
Log:
SLING-2266 Don't pass requests intended to be handled and terminated by authentication handlers
Modified:
sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
sling/trunk/bundles/auth/core/src/main/resources/OSGI-INF/metatype/metatype.properties
Modified: sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java?rev=1198738&r1=1198737&r2=1198738&view=diff
==============================================================================
--- sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java (original)
+++ sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java Mon Nov 7 14:01:01 2011
@@ -39,6 +39,7 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Property;
import org.apache.felix.scr.annotations.PropertyOption;
+import org.apache.felix.scr.annotations.PropertyUnbounded;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Services;
@@ -155,6 +156,22 @@ public class SlingAuthenticator implemen
public static final String PAR_REALM_NAME = "auth.http.realm";
/**
+ * Default request URI suffix to expect to be handled by authentication
+ * handlers and not expecting to cause
+ * {@link #handleSecurity(HttpServletRequest, HttpServletResponse)} to
+ * return <code>true</code>.
+ */
+ private static final String DEFAULT_AUTH_URI_SUFFIX = "/j_security_check";
+
+ /**
+ * The name of the configuration property used to set a (potentially
+ * empty) list of request URI suffixes intended to be handled by
+ * authentication handlers.
+ */
+ @Property(value = DEFAULT_AUTH_URI_SUFFIX, unbounded = PropertyUnbounded.ARRAY)
+ public static final String PAR_AUTH_URI_SUFFIX = "auth.uri.suffix";
+
+ /**
* The name of the {@link AuthenticationInfo} property providing the option
* {@link org.apache.sling.auth.core.spi.AuthenticationFeedbackHandler}
* handler to be called back on login failure or success.
@@ -206,6 +223,15 @@ public class SlingAuthenticator implemen
/** Cache control flag */
private boolean cacheControl;
+ /**
+ * The configured URI suffices indicating a authentication requests and
+ * requiring redirects and thus returning <code>false</code> from the
+ * #handleSecurity method.
+ * <p>
+ * This will be <code>null</code> if there are no suffices to consider.
+ */
+ private String[] authUriSuffices;
+
/** HTTP Basic authentication handler */
private HttpBasicAuthenticationHandler httpBasicHandler;
@@ -310,6 +336,9 @@ public class SlingAuthenticator implemen
}
}
+ authUriSuffices = OsgiUtil.toStringArray(properties.get(PAR_AUTH_URI_SUFFIX),
+ new String[] { DEFAULT_AUTH_URI_SUFFIX });
+
// don't require authentication for login/logout servlets
authRequiredCache.addHolder(new AuthenticationRequirementHolder(
LoginServlet.SERVLET_PATH, false, null));
@@ -387,55 +416,60 @@ public class SlingAuthenticator implemen
return true;
} else if (sessionAttr != null) {
// warn and remove existing non-session
- log.warn(
- "handleSecurity: Overwriting existing ResourceResolver attribute ({})",
- sessionAttr);
+ log.warn("handleSecurity: Overwriting existing ResourceResolver attribute ({})", sessionAttr);
request.removeAttribute(REQUEST_ATTRIBUTE_RESOLVER);
}
- AuthenticationInfo authInfo = null;
+ boolean process = doHandleSecurity(request, response);
+ if (process && expectAuthenticationHandler(request)) {
+ log.warn("handleSecurity: AuthenticationHandler did not block request; access denied");
+ request.removeAttribute(AuthenticationHandler.FAILURE_REASON);
+ AbstractAuthenticationHandler.sendInvalid(request, response);
+ return false;
+ }
+
+ return process;
+ }
+
+ private boolean doHandleSecurity(HttpServletRequest request, HttpServletResponse response) {
+
+ // 1. Ask all authentication handlers to try to extract credentials
+ final AuthenticationInfo authInfo = getAuthenticationInfo(request, response);
+
+ // 2. PostProcess credentials
+ final AuthenticationInfo aiPostProc = (authInfo == null)
+ ? new AuthenticationInfo("anonymous", "[null]")
+ : authInfo;
try {
- // 1. Ask all authentication handlers to try to extract credentials
- authInfo = getAuthenticationInfo(request, response);
+ postProcess(aiPostProc, request, response);
+ } catch (LoginException e) {
+ handleLoginFailure(request, response, aiPostProc.getUser(), e);
+ return false;
+ }
- // 2. Check Credentials
- if (authInfo == AuthenticationInfo.DOING_AUTH) {
+ // 3. Check Credentials
+ if (authInfo == AuthenticationInfo.DOING_AUTH) {
- log.debug("handleSecurity: ongoing authentication in the handler");
- return false;
+ log.debug("doHandleSecurity: ongoing authentication in the handler");
+ return false;
- } else if (authInfo == AuthenticationInfo.FAIL_AUTH) {
+ } else if (authInfo == AuthenticationInfo.FAIL_AUTH) {
- log.debug("handleSecurity: Credentials present but not valid, request authentication again");
- AbstractAuthenticationHandler.setLoginResourceAttribute(
- request, request.getRequestURI());
- doLogin(request, response);
- return false;
+ log.debug("doHandleSecurity: Credentials present but not valid, request authentication again");
+ AbstractAuthenticationHandler.setLoginResourceAttribute(request, request.getRequestURI());
+ doLogin(request, response);
+ return false;
- } else if (authInfo == null) {
- // create an empty authentication info object which can be used
- // with the post processors
- AuthenticationInfo anonInfo = new AuthenticationInfo(
- "anonymous");
- postProcess(anonInfo, request, response);
+ } else if (authInfo == null) {
- log.debug("handleSecurity: No credentials in the request, anonymous");
- return getAnonymousResolver(request, response);
+ log.debug("doHandleSecurity: No credentials in the request, anonymous");
+ return getAnonymousResolver(request, response);
- } else {
+ } else {
- log.debug("handleSecurity: Trying to get a session for {}",
- authInfo.getUser());
- return getResolver(request, response, authInfo);
+ log.debug("doHandleSecurity: Trying to get a session for {}", authInfo.getUser());
+ return getResolver(request, response, authInfo);
- }
- } catch (LoginException e) {
- if (authInfo != null) {
- handleLoginFailure(request, response, authInfo.getUser(), e);
- } else {
- handleLoginFailure(request, response, "<null>", e);
- }
- return false;
}
}
@@ -598,9 +632,7 @@ public class SlingAuthenticator implemen
// ---------- internal
- private AuthenticationInfo getAuthenticationInfo(
- HttpServletRequest request, HttpServletResponse response)
- throws LoginException {
+ private AuthenticationInfo getAuthenticationInfo(HttpServletRequest request, HttpServletResponse response) {
// Get the path used to select the authenticator, if the SlingServlet
// itself has been requested without any more info, this will be null
@@ -621,9 +653,6 @@ public class SlingAuthenticator implemen
request, response);
if (authInfo != null) {
- // post process the AuthenticationInfo object
- postProcess(authInfo, request, response);
-
// add the feedback handler to the info (may be null)
authInfo.put(AUTH_INFO_PROP_FEEDBACK_HANDLER,
holder.getFeedbackHandler());
@@ -640,9 +669,6 @@ public class SlingAuthenticator implemen
final AuthenticationInfo authInfo = httpBasicHandler.extractCredentials(
request, response);
if (authInfo != null) {
- // post process the AuthenticationInfo object
- postProcess(authInfo, request, response);
-
authInfo.put(AUTH_INFO_PROP_FEEDBACK_HANDLER, httpBasicHandler);
return authInfo;
}
@@ -758,6 +784,18 @@ public class SlingAuthenticator implemen
}
+ private boolean expectAuthenticationHandler(final HttpServletRequest request) {
+ if (this.authUriSuffices != null) {
+ final String requestUri = request.getRequestURI();
+ for (final String uriSuffix : this.authUriSuffices) {
+ if (requestUri.endsWith(uriSuffix)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
/** Try to acquire an anonymous ResourceResolver */
private boolean getAnonymousResolver(final HttpServletRequest request,
final HttpServletResponse response) {
Modified: sling/trunk/bundles/auth/core/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/core/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=1198738&r1=1198737&r2=1198738&view=diff
==============================================================================
--- sling/trunk/bundles/auth/core/src/main/resources/OSGI-INF/metatype/metatype.properties (original)
+++ sling/trunk/bundles/auth/core/src/main/resources/OSGI-INF/metatype/metatype.properties Mon Nov 7 14:01:01 2011
@@ -56,6 +56,16 @@ sling.auth.requirements.description = De
run time with additional entries: One entry is added for the "Allow Anonymous \
Access" configuration. Other entries are added for any services setting the \
"sling.auth.requirements" service registration property.
+
+auth.uri.suffix.name = Authentication URI Suffices
+auth.uri.suffix.description = A list of request URI suffixes intended to \
+ be handled by Authentication Handlers. Any request whose request URI \
+ ends with any one of the listed suffices is intended to be handled by \
+ an Authentication Handler causing the request to either be rejected or \
+ the client being redirected to another location and thus the request not \
+ being further processed after the authentication phase. The default is \
+ just "/j_security_check" which is the suffix defined by the Servlet API \
+ specification used for FORM based authentication.
auth.sudo.cookie.name = Impersonation Cookie
auth.sudo.cookie.description = The name the HTTP Cookie to set with the value \