Author: cziegeler
Date: Wed Jun 11 05:22:10 2008
New Revision: 666639
URL: http://svn.apache.org/viewvc?rev=666639&view=rev
Log:
SLING-523: Authentication handlers can be configured with paths.
Modified:
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java
incubator/sling/trunk/extensions/httpauth/src/main/java/org/apache/sling/httpauth/impl/AuthorizationHeaderAuthenticationHandler.java
Modified:
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java?rev=666639&r1=666638&r2=666639&view=diff
==============================================================================
---
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java
(original)
+++
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/auth/AuthenticationHandler.java
Wed Jun 11 05:22:10 2008
@@ -32,6 +32,13 @@
public interface AuthenticationHandler {
/**
+ * An authentication handler is associated with url paths.
+ * If the handler is not configured with a path, it is regarded as
inactive.
+ * If the handler should be used for all requests, the path should be '/'.
+ */
+ String PATH_PROPERTY = "path";
+
+ /**
* Extracts credential data from the request if at all contained.
* <p>
* The method returns any of the following values : <table>
Modified:
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java?rev=666639&r1=666638&r2=666639&view=diff
==============================================================================
---
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java
(original)
+++
incubator/sling/trunk/engine/src/main/java/org/apache/sling/engine/impl/auth/SlingAuthenticator.java
Wed Jun 11 05:22:10 2008
@@ -19,8 +19,12 @@
package org.apache.sling.engine.impl.auth;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
import java.util.Dictionary;
import java.util.Hashtable;
+import java.util.List;
import javax.jcr.Credentials;
import javax.jcr.LoginException;
@@ -32,12 +36,14 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.sling.commons.osgi.OsgiUtil;
import org.apache.sling.engine.EngineConstants;
import org.apache.sling.engine.auth.AuthenticationHandler;
import org.apache.sling.engine.auth.AuthenticationInfo;
import org.apache.sling.jcr.api.TooManySessionsException;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.cm.ManagedService;
import org.osgi.service.http.HttpContext;
@@ -111,7 +117,7 @@
private int authHandlerTrackerCount;
- private AuthenticationHandler[] authHandlerCache;
+ private AuthenticationHandlerInfo[] authHandlerCache;
/** The name of the impersonation parameter */
private String sudoParameterName;
@@ -246,20 +252,22 @@
public void requestAuthentication(HttpServletRequest request,
HttpServletResponse response) {
- AuthenticationHandler[] handlers = getAuthenticationHandlers();
+ AuthenticationHandlerInfo[] handlerInfos = getAuthenticationHandlers();
boolean done = false;
- for (int i = 0; !done && i < handlers.length; i++) {
- log.debug(
- "requestAuthentication: requesting authentication using
handler: {0}",
- handlers[i]);
-
- try {
- done = handlers[i].requestAuthentication(request, response);
- } catch (IOException ioe) {
- log.error(
- "requestAuthentication: Failed sending authentication
request through handler "
- + handlers[i] + ", access forbidden", ioe);
- done = true;
+ for (int i = 0; !done && i < handlerInfos.length; i++) {
+ if ( request.getPathInfo().startsWith(handlerInfos[i].path) ) {
+ log.debug(
+ "requestAuthentication: requesting authentication using
handler: {0}",
+ handlerInfos[i]);
+
+ try {
+ done =
handlerInfos[i].handler.requestAuthentication(request, response);
+ } catch (IOException ioe) {
+ log.error(
+ "requestAuthentication: Failed sending authentication
request through handler "
+ + handlerInfos[i] + ", access forbidden", ioe);
+ done = true;
+ }
}
}
@@ -319,15 +327,32 @@
return repo;
}
- private AuthenticationHandler[] getAuthenticationHandlers() {
+ private static AuthenticationHandlerInfo[] EMPTY_INFO = new
AuthenticationHandlerInfo[0];
+ private AuthenticationHandlerInfo[] getAuthenticationHandlers() {
if (authHandlerCache == null
|| authHandlerTrackerCount <
authHandlerTracker.getTrackingCount()) {
- Object[] services = authHandlerTracker.getServices();
- AuthenticationHandler[] ac = new AuthenticationHandler[services ==
null ? 0 : services.length];
- for (int i = 0; i < ac.length; i++) {
- ac[i] = (AuthenticationHandler) services[i];
+ final ServiceReference[] services =
authHandlerTracker.getServiceReferences();
+ if ( services == null || services.length == 0 ) {
+ this.authHandlerCache = EMPTY_INFO;
+ } else {
+ final List<AuthenticationHandlerInfo> infos = new
ArrayList<AuthenticationHandlerInfo>();
+ for (int i = 0; i < services.length; i++) {
+ log.info("** Found handler reference " + services[i]);
+ final String paths[] =
OsgiUtil.toStringArray(services[i].getProperty(AuthenticationHandler.PATH_PROPERTY));
+ log.info("** Paths " + paths);
+ if ( paths != null && paths.length > 0 ) {
+ final AuthenticationHandler handler =
(AuthenticationHandler) authHandlerTracker.getService(services[i]);
+ log.info("** Handler " + handler);
+ for(int m = 0; m < paths.length; m++) {
+ log.info("** Path " + paths[m]);
+ infos.add(new AuthenticationHandlerInfo(paths[m],
handler));
+ }
+ }
+ }
+ final AuthenticationHandlerInfo[] ac = infos.toArray(new
AuthenticationHandlerInfo[infos.size()]);
+ Arrays.sort(ac, AuthenticationHandlerInfoComparator.SINGLETON);
+ authHandlerCache = ac;
}
- authHandlerCache = ac;
authHandlerTrackerCount = authHandlerTracker.getTrackingCount();
}
return authHandlerCache;
@@ -335,12 +360,14 @@
private AuthenticationInfo getAuthenticationInfo(
HttpServletRequest request, HttpServletResponse response) {
- AuthenticationHandler[] local = getAuthenticationHandlers();
+ AuthenticationHandlerInfo[] local = getAuthenticationHandlers();
for (int i = 0; i < local.length; i++) {
- AuthenticationInfo authInfo = local[i].authenticate(request,
- response);
- if (authInfo != null) {
- return authInfo;
+ if ( request.getPathInfo().startsWith(local[i].path) ) {
+ final AuthenticationInfo authInfo =
local[i].handler.authenticate(request,
+ response);
+ if (authInfo != null) {
+ return authInfo;
+ }
}
}
@@ -558,4 +585,28 @@
return session;
}
+ protected static final class AuthenticationHandlerInfo {
+ public final String path;
+ public final AuthenticationHandler handler;
+
+ public AuthenticationHandlerInfo(final String p, final
AuthenticationHandler h) {
+ this.path = p;
+ this.handler = h;
+ }
+ }
+
+ protected static final class AuthenticationHandlerInfoComparator
implements Comparator<AuthenticationHandlerInfo> {
+
+ public static final AuthenticationHandlerInfoComparator SINGLETON =
new AuthenticationHandlerInfoComparator();
+ /**
+ * @see java.util.Comparator#compare(java.lang.Object,
java.lang.Object)
+ */
+ public int compare(AuthenticationHandlerInfo arg0,
+ AuthenticationHandlerInfo arg1) {
+ return arg0.path.compareTo(arg1.path) * -1;
+ }
+
+ }
+
+
}
Modified:
incubator/sling/trunk/extensions/httpauth/src/main/java/org/apache/sling/httpauth/impl/AuthorizationHeaderAuthenticationHandler.java
URL:
http://svn.apache.org/viewvc/incubator/sling/trunk/extensions/httpauth/src/main/java/org/apache/sling/httpauth/impl/AuthorizationHeaderAuthenticationHandler.java?rev=666639&r1=666638&r2=666639&view=diff
==============================================================================
---
incubator/sling/trunk/extensions/httpauth/src/main/java/org/apache/sling/httpauth/impl/AuthorizationHeaderAuthenticationHandler.java
(original)
+++
incubator/sling/trunk/extensions/httpauth/src/main/java/org/apache/sling/httpauth/impl/AuthorizationHeaderAuthenticationHandler.java
Wed Jun 11 05:22:10 2008
@@ -38,11 +38,12 @@
* the authorization steps based on the Authorization header of the HTTP
* request. This authenticator should eventually support both BASIC and DIGEST
* authentication methods.
- *
+ *
* @scr.component immediate="false" label="%auth.http.name"
* description="%auth.http.description"
* @scr.property name="service.description" value="HTTP Header Authentication
Handler"
* @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property nameRef="AuthenticationHandler.PATH_PROPERTY" value="/"
* @scr.service
*/
public class AuthorizationHeaderAuthenticationHandler implements
@@ -58,7 +59,7 @@
* in the [EMAIL PROTECTED] #authenticate(HttpServletRequest,
HttpServletResponse)}
* method if no credentials are present in the request (value is
* "sling:authRequestLogin").
- *
+ *
* @see #authenticate(HttpServletRequest, HttpServletResponse)
*/
static final String REQUEST_LOGIN_PARAMETER = "sling:authRequestLogin";
@@ -119,7 +120,7 @@
* the request may be for an included servlet, in which case the values for
* some URI specific values are contained in javax.servlet.include.*
request
* attributes.
- *
+ *
* @param request The request object containing the information for the
* authentication.
* @param response The response object which may be used to send the
@@ -159,7 +160,7 @@
* authentication with the <code>Basic</code> scheme and the configured
* realm name. If the response is already committed, an error message is
* logged but the 401 status is not sent.
- *
+ *
* @param request The request object
* @param response The response object to which to send the request
* @return <code>true</code> is always returned by this handler