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 2010/09/13 12:08:53 UTC
svn commit: r996477 - in /sling/trunk/bundles/auth:
core/src/main/java/org/apache/sling/auth/core/impl/
core/src/main/java/org/apache/sling/auth/core/spi/ form/
form/src/main/java/org/apache/sling/auth/form/impl/ openid/ selector/
selector/src/main/jav...
Author: fmeschbe
Date: Mon Sep 13 10:08:52 2010
New Revision: 996477
URL: http://svn.apache.org/viewvc?rev=996477&view=rev
Log:
SLING-1752 Unify resource attribute/parameter setting and default value handling
Modified:
sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/HttpBasicAuthenticationHandler.java
sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LoginServlet.java
sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LogoutServlet.java
sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/SlingAuthenticator.java
sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/spi/AbstractAuthenticationHandler.java
sling/trunk/bundles/auth/form/pom.xml
sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
sling/trunk/bundles/auth/openid/pom.xml
sling/trunk/bundles/auth/selector/pom.xml
sling/trunk/bundles/auth/selector/src/main/java/org/apache/sling/auth/selector/SelectorAuthenticationHandler.java
Modified: sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/HttpBasicAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/HttpBasicAuthenticationHandler.java?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/HttpBasicAuthenticationHandler.java (original)
+++ sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/HttpBasicAuthenticationHandler.java Mon Sep 13 10:08:52 2010
@@ -234,6 +234,17 @@ class HttpBasicAuthenticationHandler ext
response.resetBuffer();
+ /*
+ * TODO: Check whether we have to redirect
+ * If this is a GET request not targeted at the registration path
+ * for which this handler is selected we have to redirect to the
+ * registration path using either the provided resource attribute
+ * or parameter or the current URL as the "resource" parameter
+ * for the redirect and also setting the "sling:authRequestLogin"
+ * parameter to "BASIC" to get the 401 response for the registration
+ * path and redirect back to actual path afterwards.
+ */
+
// just set the status because this may be called as part of an
// error handler in which case sendError would result in an error
// handler loop and thus be ignored.
Modified: sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LoginServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LoginServlet.java?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LoginServlet.java (original)
+++ sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LoginServlet.java Mon Sep 13 10:08:52 2010
@@ -35,6 +35,7 @@ import org.apache.sling.api.SlingHttpSer
import org.apache.sling.api.auth.Authenticator;
import org.apache.sling.api.auth.NoAuthenticationHandlerException;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
+import org.apache.sling.auth.core.spi.AbstractAuthenticationHandler;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -70,7 +71,6 @@ public class LoginServlet extends SlingA
protected void service(SlingHttpServletRequest request,
SlingHttpServletResponse response) throws IOException {
- final String resourcePath = request.getParameter(Authenticator.LOGIN_RESOURCE);
// if the request is logged in and the resource is not set (such
// as when requesting /system/sling/login from the browser with the
@@ -79,6 +79,8 @@ public class LoginServlet extends SlingA
// through the login servlet), redirect to root now assuming we are
// authenticated.
if (request.getAuthType() != null) {
+ final String resourcePath = AbstractAuthenticationHandler.getLoginResource(
+ request, null);
if (isSelf(resourcePath)) {
String redirectTarget = request.getContextPath() + "/";
log.warn(
@@ -94,8 +96,8 @@ public class LoginServlet extends SlingA
try {
// set the login resource to select the authenticator
- request.setAttribute(Authenticator.LOGIN_RESOURCE,
- (resourcePath != null) ? resourcePath : "/");
+ AbstractAuthenticationHandler.setLoginResourceAttribute(
+ request, request.getContextPath());
authenticator.login(request, response);
return;
Modified: sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LogoutServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LogoutServlet.java?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LogoutServlet.java (original)
+++ sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/impl/LogoutServlet.java Mon Sep 13 10:08:52 2010
@@ -32,6 +32,7 @@ import org.apache.sling.api.SlingHttpSer
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.auth.Authenticator;
import org.apache.sling.api.servlets.SlingAllMethodsServlet;
+import org.apache.sling.auth.core.spi.AbstractAuthenticationHandler;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -70,10 +71,8 @@ public class LogoutServlet extends Sling
final Authenticator authenticator = this.authenticator;
if (authenticator != null) {
try {
- final String resourcePath = request.getParameter("resource");
- request.setAttribute(Authenticator.LOGIN_RESOURCE,
- (resourcePath != null) ? resourcePath : "/");
-
+ AbstractAuthenticationHandler.setLoginResourceAttribute(
+ request, request.getContextPath());
authenticator.logout(request, response);
return;
} catch (IllegalStateException ise) {
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=996477&r1=996476&r2=996477&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 Sep 13 10:08:52 2010
@@ -379,9 +379,8 @@ public class SlingAuthenticator implemen
} else if (authInfo == AuthenticationInfo.FAIL_AUTH) {
log.debug("handleSecurity: Credentials present but not valid, request authentication again");
- request.setAttribute(LOGIN_RESOURCE,
- AbstractAuthenticationHandler.getLoginResource(request,
- request.getRequestURI()));
+ AbstractAuthenticationHandler.setLoginResourceAttribute(
+ request, request.getRequestURI());
doLogin(request, response);
return false;
@@ -1042,12 +1041,21 @@ public class SlingAuthenticator implemen
*/
private String getHandlerSelectionPath(HttpServletRequest request) {
final Object loginPathO = request.getAttribute(Authenticator.LOGIN_RESOURCE);
- String path = (loginPathO instanceof String)
- ? (String) loginPathO
- : request.getPathInfo();
+ String path;
+ if (loginPathO instanceof String) {
+ path = (String) loginPathO;
+ final String ctxPath = request.getContextPath();
+ if (ctxPath != null && path.startsWith(ctxPath)) {
+ path = path.substring(ctxPath.length());
+ }
+ } else {
+ path = request.getPathInfo();
+ }
+
if (path == null || path.length() == 0) {
path = "/";
}
+
return path;
}
@@ -1071,18 +1079,14 @@ public class SlingAuthenticator implemen
return;
}
- // check resource attribute/parameter
- String target = (String) request.getAttribute(LOGIN_RESOURCE);
- if (target == null || target.length() == 0) {
- target = request.getParameter(LOGIN_RESOURCE);
- if (target == null || target.length() == 0) {
- target = "/";
- }
- }
+ // find the redirect target from the resource attribute or parameter
+ // falling back to the reuest context path (or /) if not set
+ final String target = AbstractAuthenticationHandler.setLoginResourceAttribute(
+ request, request.getContextPath());
// redirect to there
try {
- response.sendRedirect(request.getContextPath() + target);
+ response.sendRedirect(target);
} catch (IOException e) {
log.error("Failed to redirect to the page: " + target, e);
}
Modified: sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/spi/AbstractAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/spi/AbstractAuthenticationHandler.java?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/spi/AbstractAuthenticationHandler.java (original)
+++ sling/trunk/bundles/auth/core/src/main/java/org/apache/sling/auth/core/spi/AbstractAuthenticationHandler.java Mon Sep 13 10:08:52 2010
@@ -52,9 +52,9 @@ public abstract class AbstractAuthentica
final HttpServletRequest request, final String name,
final String defaultValue) {
- Object resObj = request.getAttribute(name);
- if ((resObj instanceof String) && ((String) resObj).length() > 0) {
- return (String) resObj;
+ final String resourceAttr = getAttributeString(request, name);
+ if (resourceAttr != null) {
+ return resourceAttr;
}
final String resource = request.getParameter(name);
@@ -83,4 +83,59 @@ public abstract class AbstractAuthentica
return getAttributeOrParameter(request, Authenticator.LOGIN_RESOURCE,
defaultLoginResource);
}
+
+ /**
+ * Ensures and returns the {@link Authenticator#LOGIN_RESOURCE} request
+ * attribute is set to a non-null, non-empty string. If the attribute is not
+ * currently set, this method sets it as follows:
+ * <ol>
+ * <li>If the {@link Authenticator#LOGIN_RESOURCE} request parameter is set
+ * to a non-empty string, that parameter is set</li>
+ * <li>Otherwise if the <code>defaultValue</code> is a non-empty string the
+ * default value is used</li>
+ * <li>Otherwise the attribute is set to "/"</li>
+ * </ol>
+ *
+ * @param request The request to check for the resource attribute
+ * @param defaultValue The default value to use if the attribute is not set
+ * and the request parameter is not set. This parameter is
+ * ignored if it is <code>null</code> or an empty string.
+ * @return returns the value of resource request attribute
+ */
+ public static String setLoginResourceAttribute(
+ final HttpServletRequest request, final String defaultValue) {
+ String resourceAttr = getAttributeString(request,
+ Authenticator.LOGIN_RESOURCE);
+ if (resourceAttr == null) {
+ final String resourcePar = request.getParameter(Authenticator.LOGIN_RESOURCE);
+ if (resourcePar != null && resourcePar.length() > 0) {
+ resourceAttr = resourcePar;
+ } else if (defaultValue != null && defaultValue.length() > 0) {
+ resourceAttr = defaultValue;
+ } else {
+ resourceAttr = "/";
+ }
+ request.setAttribute(Authenticator.LOGIN_RESOURCE, resourceAttr);
+ }
+ return resourceAttr;
+ }
+
+ /**
+ * Returns the name request attribute if it is a non-empty string value.
+ *
+ * @param request The request from which to retrieve the attribute
+ * @param name The name of the attribute to return
+ * @return The named request attribute or <code>null</code> if the attribute
+ * is not set or is not a non-empty string value.
+ */
+ private static String getAttributeString(final HttpServletRequest request,
+ final String name) {
+ Object resObj = request.getAttribute(name);
+ if ((resObj instanceof String) && ((String) resObj).length() > 0) {
+ return (String) resObj;
+ }
+
+ // not set or not a non-empty string
+ return null;
+ }
}
Modified: sling/trunk/bundles/auth/form/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/form/pom.xml?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/form/pom.xml (original)
+++ sling/trunk/bundles/auth/form/pom.xml Mon Sep 13 10:08:52 2010
@@ -98,7 +98,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.auth.core</artifactId>
- <version>1.0.0</version>
+ <version>1.0.3-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java (original)
+++ sling/trunk/bundles/auth/form/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java Mon Sep 13 10:08:52 2010
@@ -330,13 +330,26 @@ public class FormAuthenticationHandler e
if (authData != null) {
if (tokenStore.isValid(authData)) {
info = createAuthInfo(authData);
+ } else if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
+ // signal to AJAX the request is forbidden
+ try {
+ response.sendError(
+ HttpServletResponse.SC_REQUEST_TIMEOUT,
+ "Session Timeout, please login");
+ response.flushBuffer();
+ } catch (IOException ioe) {
+ // TODO: log !!
+ }
+ return AuthenticationInfo.DOING_AUTH;
} else {
if (this.loginAfterExpire) {
- // signal the requestCredentials method a previous login failure
- request.setAttribute(PAR_J_REASON, FormReason.TIMEOUT);
- info = AuthenticationInfo.FAIL_AUTH;
+ // signal the requestCredentials method a previous login
+ // failure
+ request.setAttribute(PAR_J_REASON, FormReason.TIMEOUT);
+ info = AuthenticationInfo.FAIL_AUTH;
}
- // clear the cookie, its invalid and we should get rid of it so that the invalid cookie
+ // clear the cookie, its invalid and we should get rid of it
+ // so that the invalid cookie
// isn't present on the authN operation.
authStorage.clear(request, response);
}
@@ -379,11 +392,8 @@ public class FormAuthenticationHandler e
return true;
}
- String resource = getLoginResource(request, null);
- if (resource == null) {
- resource = request.getContextPath() + request.getPathInfo();
- request.setAttribute(Authenticator.LOGIN_RESOURCE, resource);
- }
+ final String resource = setLoginResourceAttribute(request,
+ request.getRequestURI());
if (includeLoginForm && (resourceResolverFactory != null)) {
ResourceResolver resourceResolver = null;
@@ -651,9 +661,7 @@ public class FormAuthenticationHandler e
// authentication, otherwise the request may be processed
// as a POST request to the j_security_check page (unless
// the j_validate parameter is set)
- if (getLoginResource(request, null) == null) {
- request.setAttribute(Authenticator.LOGIN_RESOURCE, "/");
- }
+ setLoginResourceAttribute(request, request.getContextPath());
}
}
@@ -896,6 +904,15 @@ public class FormAuthenticationHandler e
* {@link CookieAuthData} in an HTTP Cookie.
*/
private static class CookieStorage implements AuthenticationStorage {
+
+ /**
+ * The Set-Cookie header used to manage the login cookie.
+ *
+ * @see CookieStorage#setCookie(HttpServletRequest, HttpServletResponse,
+ * String, String, int, String)
+ */
+ private static final String HEADER_SET_COOKIE = "Set-Cookie";
+
private final String cookieName;
private final String domainCookieName;
private final String defaultCookieDomain;
@@ -917,8 +934,11 @@ public class FormAuthenticationHandler e
// reverse the base64 encoding
try {
- return new String(Base64.decodeBase64(value),
- "UTF-8");
+ String result = new String(
+ Base64.decodeBase64(value), "UTF-8");
+ if (result.length() > 0) {
+ return result;
+ }
} catch (UnsupportedEncodingException e1) {
throw new RuntimeException(e1);
}
@@ -988,14 +1008,37 @@ public class FormAuthenticationHandler e
? "/"
: ctxPath;
- Cookie cookie = new Cookie(name, value);
+ /*
+ * The Servlet Spec 2.5 does not allow us to set the commonly used
+ * HttpOnly attribute on cookies (Servlet API 3.0 does) so we create
+ * the Set-Cookie header manually. See
+ * http://www.owasp.org/index.php/HttpOnly for information on what
+ * the HttpOnly attribute is used for.
+ */
+
+ final StringBuilder header = new StringBuilder();
+
+ // default setup with name, value, cookie path and HttpOnly
+ header.append(name).append('=').append(value);
+ header.append(";Path=").append(cookiePath);
+ header.append(";HttpOnly"); // don't allow JS access
+
+ // set the cookie domain if so configured
if (domain != null) {
- cookie.setDomain(domain);
+ header.append(";Domain=").append(domain);
+ }
+
+ // Only set the Max-Age attribute to remove the cookie
+ if (age == 0) {
+ header.append(";Max-Age=").append(age);
}
- cookie.setMaxAge(age);
- cookie.setPath(cookiePath);
- cookie.setSecure(request.isSecure());
- response.addCookie(cookie);
+
+ // ensure the cookie is secured if this is an https request
+ if (request.isSecure()) {
+ header.append(";Secure");
+ }
+
+ response.addHeader(HEADER_SET_COOKIE, header.toString());
}
}
Modified: sling/trunk/bundles/auth/openid/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/openid/pom.xml?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/openid/pom.xml (original)
+++ sling/trunk/bundles/auth/openid/pom.xml Mon Sep 13 10:08:52 2010
@@ -107,7 +107,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.auth.core</artifactId>
- <version>1.0.0</version>
+ <version>1.0.3-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: sling/trunk/bundles/auth/selector/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/selector/pom.xml?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/selector/pom.xml (original)
+++ sling/trunk/bundles/auth/selector/pom.xml Mon Sep 13 10:08:52 2010
@@ -100,7 +100,7 @@
<dependency>
<groupId>org.apache.sling</groupId>
<artifactId>org.apache.sling.auth.core</artifactId>
- <version>1.0.0</version>
+ <version>1.0.3-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
Modified: sling/trunk/bundles/auth/selector/src/main/java/org/apache/sling/auth/selector/SelectorAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/auth/selector/src/main/java/org/apache/sling/auth/selector/SelectorAuthenticationHandler.java?rev=996477&r1=996476&r2=996477&view=diff
==============================================================================
--- sling/trunk/bundles/auth/selector/src/main/java/org/apache/sling/auth/selector/SelectorAuthenticationHandler.java (original)
+++ sling/trunk/bundles/auth/selector/src/main/java/org/apache/sling/auth/selector/SelectorAuthenticationHandler.java Mon Sep 13 10:08:52 2010
@@ -96,54 +96,42 @@ public class SelectorAuthenticationHandl
public boolean requestCredentials(HttpServletRequest request,
HttpServletResponse response) throws IOException {
- String resource = getLoginResource(request, null);
- if (resource == null) {
- resource = request.getContextPath() + request.getPathInfo();
- request.setAttribute(Authenticator.LOGIN_RESOURCE, resource);
- }
// prepare the login form redirection target
final StringBuilder targetBuilder = new StringBuilder();
targetBuilder.append(request.getContextPath());
targetBuilder.append(loginForm);
- // append originally requested resource (for redirect after login)
- char parSep = '?';
-
- if (resource != null) {
- targetBuilder.append(parSep).append(Authenticator.LOGIN_RESOURCE);
- targetBuilder.append("=").append(
- URLEncoder.encode(resource, "UTF-8"));
- parSep = '&';
- }
+ targetBuilder.append('?').append(Authenticator.LOGIN_RESOURCE);
+ targetBuilder.append("=").append(
+ URLEncoder.encode(
+ setLoginResourceAttribute(request, request.getRequestURI()),
+ "UTF-8"));
// append indication of previous login failure
if (request.getAttribute(PAR_J_REASON) != null) {
final Object jReason = request.getAttribute(PAR_J_REASON);
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
final String reason = (jReason instanceof Enum)
? ((Enum) jReason).name()
: jReason.toString();
- targetBuilder.append(parSep).append(PAR_J_REASON);
+ targetBuilder.append('&').append(PAR_J_REASON);
targetBuilder.append("=").append(URLEncoder.encode(reason, "UTF-8"));
- parSep = '&';
} else if (request.getAttribute(OpenIDConstants.OPENID_FAILURE_REASON) != null) {
final Object jReason = request.getAttribute(OpenIDConstants.OPENID_FAILURE_REASON);
- @SuppressWarnings("unchecked")
+ @SuppressWarnings("rawtypes")
final String reason = (jReason instanceof Enum)
? ((Enum) jReason).name()
: jReason.toString();
- targetBuilder.append(parSep).append(PAR_J_REASON);
+ targetBuilder.append('&').append(PAR_J_REASON);
targetBuilder.append("=").append(URLEncoder.encode(reason, "UTF-8"));
- parSep = '&';
}
// append selected authentication type of previous request
if (request.getParameter(PAR_SELECTED_AUTH_TYPE) != null) {
- targetBuilder.append(parSep).append(PAR_SELECTED_AUTH_TYPE);
+ targetBuilder.append('&').append(PAR_SELECTED_AUTH_TYPE);
targetBuilder.append("=").append(
request.getParameter(PAR_SELECTED_AUTH_TYPE));
- parSep = '&';
}
// finally redirect to the login form