You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ju...@apache.org on 2010/06/23 23:30:55 UTC

svn commit: r957356 - in /sling/trunk/bundles/extensions/formauth: ./ src/main/java/org/apache/sling/formauth/impl/ src/main/resources/OSGI-INF/metatype/

Author: justin
Date: Wed Jun 23 21:30:55 2010
New Revision: 957356

URL: http://svn.apache.org/viewvc?rev=957356&view=rev
Log:
SLING-1564 - adding support for form inclusion as well as custom form pages via fragments

Modified:
    sling/trunk/bundles/extensions/formauth/pom.xml
    sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
    sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
    sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties

Modified: sling/trunk/bundles/extensions/formauth/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/pom.xml?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/pom.xml (original)
+++ sling/trunk/bundles/extensions/formauth/pom.xml Wed Jun 23 21:30:55 2010
@@ -117,6 +117,12 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.0.9-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>org.osgi</groupId>
             <artifactId>org.osgi.core</artifactId>
         </dependency>

Modified: sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java (original)
+++ sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java Wed Jun 23 21:30:55 2010
@@ -58,6 +58,10 @@ public class AuthenticationFormServlet e
     @SuppressWarnings("unused")
     private static final String AUTH_REQUIREMENT = "-" + SERVLET_PATH;
 
+    private static final String DEFAULT_FORM_PATH = "login.html";
+
+    private static final String CUSTOM_FORM_PATH = "custom_login.html";
+
     /**
      * The raw form used by the {@link #getForm(HttpServletRequest)} method to
      * fill in with per-request data. This field is set by the
@@ -82,7 +86,30 @@ public class AuthenticationFormServlet e
     @Override
     protected void doGet(HttpServletRequest request,
             HttpServletResponse response) throws IOException {
+        handle(request, response);
+    }
+
+    /**
+     * Prepares and returns the login form. The response is sent as an UTF-8
+     * encoded <code>text/html</code> page with all known cache control headers
+     * set to prevent all caching.
+     * <p>
+     * This servlet is to be called to handle the request directly, that is it
+     * expected to not be included and for the response to not be committed yet
+     * because it first resets the response.
+     *
+     * @throws IOException if an error occurrs preparing or sending back the
+     *             login form
+     * @throws IllegalStateException if the response has already been committed
+     *             and thus response reset is not possible.
+     */
+    @Override
+    protected void doPost(HttpServletRequest request,
+            HttpServletResponse response) throws IOException {
+        handle(request, response);
+    }
 
+    private void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
         // reset the response first
         response.reset();
 
@@ -143,6 +170,12 @@ public class AuthenticationFormServlet e
      *         string if there is no specific reason
      */
     private String getReason(final HttpServletRequest request) {
+        // return the resource attribute if set to a non-empty string
+        Object resObj = request.getAttribute(FormAuthenticationHandler.PAR_J_REASON);
+        if (resObj instanceof FormReason) {
+            return ((FormReason) resObj).toString();
+        }
+
         final String reason = request.getParameter(FormAuthenticationHandler.PAR_J_REASON);
         if (reason != null) {
             try {
@@ -150,7 +183,7 @@ public class AuthenticationFormServlet e
             } catch (IllegalArgumentException iae) {
                 // thrown if the reason is not an expected value, assume none
             }
-            
+
             // no valid FormReason value, use raw value
             return reason;
         }
@@ -169,7 +202,13 @@ public class AuthenticationFormServlet e
         if (rawForm == null) {
             InputStream ins = null;
             try {
-                ins = getClass().getResourceAsStream("login.html");
+                // try a custom login page first.
+                ins = getClass().getResourceAsStream(CUSTOM_FORM_PATH);
+                if (ins == null) {
+                    // try the standard login page
+                    ins = getClass().getResourceAsStream(DEFAULT_FORM_PATH);
+                }
+
                 if (ins != null) {
                     StringBuilder builder = new StringBuilder();
                     Reader r = new InputStreamReader(ins, "UTF-8");

Modified: sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java (original)
+++ sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java Wed Jun 23 21:30:55 2010
@@ -28,6 +28,8 @@ import java.util.Dictionary;
 
 import javax.jcr.Credentials;
 import javax.jcr.SimpleCredentials;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
 import javax.servlet.http.Cookie;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
@@ -35,6 +37,10 @@ import javax.servlet.http.HttpSession;
 
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
 import org.apache.sling.commons.auth.Authenticator;
 import org.apache.sling.commons.auth.spi.AuthenticationFeedbackHandler;
 import org.apache.sling.commons.auth.spi.AuthenticationHandler;
@@ -151,6 +157,21 @@ public class FormAuthenticationHandler i
     private static final String DEFAULT_TOKEN_FILE = "cookie-tokens.bin";
 
     /**
+     * Whether to redirect to the login form or simple do an include.
+     *
+     * @scr.property type="Boolean" valueRef="DEFAULT_INCLUDE_FORM"
+     */
+    public static final String PAR_INCLUDE_FORM = "form.use.include";
+
+    /**
+     * The default include value.
+     *
+     * @see #PAR_INCLUDE_FORM
+     */
+    private static final boolean DEFAULT_INCLUDE_FORM = false;
+
+
+    /**
      * The request method required for user name and password submission by the
      * form (value is "POST").
      */
@@ -247,6 +268,20 @@ public class FormAuthenticationHandler i
     private ServiceRegistration loginModule;
 
     /**
+     * If true, the handler will attempt to include the login form instead of
+     * doing a redirect.
+     */
+    private boolean includeLoginForm;
+
+    /**
+     * The resource resolver factory used to resolve the login form as a resource
+     *
+     * @scr.reference policy="dynamic" cardinality="0..1"
+     */
+    private ResourceResolverFactory resourceResolverFactory;
+
+
+    /**
      * Extracts cookie/session based credentials from the request. Returns
      * <code>null</code> if the handler assumes HTTP Basic authentication would
      * be more appropriate, if no form fields are present in the request and if
@@ -311,6 +346,35 @@ public class FormAuthenticationHandler i
             return true;
         }
 
+        String resource = getLoginResource(request);
+        if (resource == null) {
+            resource = request.getContextPath() + request.getPathInfo();
+            request.setAttribute(Authenticator.LOGIN_RESOURCE, resource);
+        }
+
+        if (includeLoginForm && (resourceResolverFactory != null)) {
+            ResourceResolver resourceResolver = null;
+            try {
+                resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
+                Resource loginFormResource = resourceResolver.resolve(loginForm);
+                Servlet loginFormServlet = loginFormResource.adaptTo(Servlet.class);
+                if (loginFormServlet != null) {
+                    try {
+                        loginFormServlet.service(request, response);
+                        return true;
+                    } catch (ServletException e) {
+                        log.error("Failed to include the form: " + loginForm, e);
+                    }
+                }
+            } catch (LoginException e) {
+                log.error("Unable to get a resource resolver to include for the login resource. Will redirect instead.");
+            } finally {
+                if (resourceResolver != null) {
+                    resourceResolver.close();
+                }
+            }
+        }
+
         // prepare the login form redirection target
         final StringBuilder targetBuilder = new StringBuilder();
         targetBuilder.append(request.getContextPath());
@@ -318,10 +382,6 @@ public class FormAuthenticationHandler i
 
         // append originally requested resource (for redirect after login)
         char parSep = '?';
-        String resource = getLoginResource(request);
-        if (resource == null) {
-            resource = request.getContextPath() + request.getPathInfo();
-        }
 
         if (resource != null) {
             targetBuilder.append(parSep).append(Authenticator.LOGIN_RESOURCE);
@@ -706,6 +766,9 @@ public class FormAuthenticationHandler i
             log.info("Cannot register FormLoginModulePlugin. This is expected if Sling LoginModulePlugin services are not supported");
             log.debug("dump", t);
         }
+
+        this.includeLoginForm = OsgiUtil.toBoolean(properties.get(PAR_INCLUDE_FORM), DEFAULT_INCLUDE_FORM);
+
     }
 
     protected void deactivate(

Modified: sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties (original)
+++ sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties Wed Jun 23 21:30:55 2010
@@ -31,7 +31,7 @@ path.description = Repository path for w
  should be used by Sling. If this is empty, the authentication handler will \
  be disabled.
 
-form.login.form.name = Login Form    
+form.login.form.name = Login Form
 form.login.form.description = The URL (without any context path prefix) to \
  redirect the client to to present the login form. The default value is \
  "/system/sling/form/login".
@@ -41,22 +41,22 @@ form.auth.storage.description = The type
  authentication state. Valid values are cookie and session. The default value \
  (cookie) also applies if any setting other than the supported values is \
  configured.
- 
+
 form.auth.name.name = Cookie/Attribute Name
 form.auth.name.description = The name of the Cookie or HTTP Session attribute \
- providing the authentication state. The default value is "sling.formauth". 
+ providing the authentication state. The default value is "sling.formauth".
 
-form.credentials.name.name = Credentials Attribute 
+form.credentials.name.name = Credentials Attribute
 form.credentials.name.description = The name of the SimpleCredentials \
  attribute used  to provide the authentication data to the LoginModulePlugin. \
  The default value is "sling.formauth".
 
-form.auth.timeout.name = Timeout  
+form.auth.timeout.name = Timeout
 form.auth.timeout.description = The number of minutes after which a login \
  session times out. This value is used as the expiry time set in the \
  authentication data. The default value is 30 minutes. If the value is set \
  a value less than 1, the default value is used instead.
- 
+
 form.token.file.name = Security Token File
 form.token.file.description = The name of the file used to persist the \
  security tokens. The default value is cookie-tokens.bin. This property \
@@ -70,3 +70,7 @@ form.token.file.description = The name o
 service.ranking.name = Ranking
 service.ranking.description = The relative ranking of this service.
 
+form.use.include.name = Include Form
+form.use.include.description = If true, this authentication handler will attempt \
+ to include a Servlet resource at the login form path. If false, a redirect will \
+ be used instead.