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


Reply via email to