You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/11/07 09:17:44 UTC

[sling-org-apache-sling-auth-form] annotated tag org.apache.sling.auth.form-1.0.0 created (now cd5b346)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git.


      at cd5b346  (tag)
 tagging 637350c9ad84623e574a4306c42e875b26d2f1d2 (commit)
      by Felix Meschberger
      on Mon Aug 23 16:25:18 2010 +0000

- Log -----------------------------------------------------------------
org.apache.sling.auth.form-1.0.0
-----------------------------------------------------------------------

This annotated tag includes the following new commits:

     new f467e0e  SLING-1116 Initial Version based on Eric Norman's patch (thanks alot)
     new 8b679bf  SLING-1116 cleanup dependencies
     new a0fcd1a  SLING-1116 Implement support for the j_validate login form parameter and add support to convey a reason to render the login form using the j_reason request parameter for the login form request
     new 44c5ccd  SLING-1116 Fix service description
     new a812358  SLING-1116 Ensure the FormLoginModulePlugin is actually registered as a service (otherwise authenticaiton may fail). Also the resource attribute is set in the extractRequestParameterAuthentication method to ensure a redirect takes place after successful login
     new 0a41f41  SLING-1380 Do not return anything from getPrincipal to allow DefaultLoginModule.getPrincipal to kick in and validate the user name against the existing users (and also to provide the correct principal for the user)
     new a25ef67  SLING-1116 make sure the login form action is an absolute path
     new 33e89b6  SLING-1419 : Remove dependency to JCR
     new 64b2394  SLING-1498 - saving resource being requested
     new 0a8abcc  SLING-1497 - adding tentative configuration for configuring service.ranking via ConfigAdmin/Metatype
     new 1cb242e  forgot that maven 3 dropped support for latest. oh well, new scr plugin should be released rsn
     new 6b812d8  Use released parent pom.
     new 4e10552  SLING-1116 Improve FormReason to convey the human-readable message by toString()
     new 217e197  SLING-1565 Move private implementation classes to the impl package and export the o.a.s.formauth package for login forms to be able to interpret the j_reason value with the FormReason enum.
     new a606003  SLING-1565 - need to move the login form as well to be in the same package as the servlet
     new d5ecfb9  SLING-1564 - adding support for form inclusion as well as custom form pages via fragments
     new 196a11f  SLING-1587 - file name wasn't being logged
     new d3222a7  SLING-1575 Adapt Form and OpenID authentication handler to use new abstract form servlet and authentication handler
     new 531e943  SLING-1575 Add @scr.service tag for login form servlets and fully qualify path property definition in the authentication handler
     new 03ed695  Remove unneeded (and commented out) version element
     new 99b1053  SLING-1588 Fixed, cookie needs to be removed when found to be invalid.
     new d24ad09  SLING-1614 Added config settings that allow a login form to be re-displayed when the login token expires, by default the login form is not displayed on expiry, on the basis that it was not displayed by default when the anon user first came to the site.
     new e561eda  SLING-1614 Added missing property name and metatype text.
     new 008d39d  SLING-1647 Set handler specific properties in the AuthenticationInfo instead of the credentials. The properties will be transferred to the session by the ResourceResolverFactory implementation
     new bdb9503  SLING-1650 Consolidate authentication stuff in a new auth component; * rename commons/auth to auth/core * rename extensions/formauth to auth/form * rename extensions/openidauth to auth/openid
     new f4f4bfc  SLING-1650 Refactor auth/core, auth/form, auth/openid for the new packages identifying the auth component and refer to the new auth/core for the authentication handlers.
     new 5ba6c25  SLING-1650 Remove old packages; make sure the login.html form source is in the correct (new) location
     new 9946c7c  Set JIRA version id and fix JavaDoc exclusions
     new dc98910  Update to Sling API 2.1.0
     new af26b77  use Auth Core 1.0.0 to prepare the release
     new 9e52b4e  [maven-release-plugin] prepare release org.apache.sling.auth.form-1.0.0
     new 637350c  [maven-scm] copy for tag org.apache.sling.auth.form-1.0.0

The 32 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-auth-form] 22/32: SLING-1614 Added config settings that allow a login form to be re-displayed when the login token expires, by default the login form is not displayed on expiry, on the basis that it was not displayed by default when the anon user first came to the site.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit d24ad09cd18505d7ed7109bd50d2a460ccd56ca6
Author: Ian Boston <ie...@apache.org>
AuthorDate: Wed Jul 28 15:59:04 2010 +0000

    SLING-1614 Added config settings that allow a login form to be re-displayed when the login token expires, by default the login form is not displayed on expiry, on the basis that it was not displayed by default when the anon user first came to the site.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@980107 13f79535-47bb-0310-9956-ffa450edef68
---
 .../formauth/impl/FormAuthenticationHandler.java   | 30 +++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index 638c04b..4c100ce 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -174,6 +174,21 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
 
 
     /**
+     * Whether to present a login form when a users cookie expires, the default
+     * is not to present the form.
+     *
+     * @scr.property type="Boolean" valueRef="DEFAULT_LOGIN_AFTER_EXPIRE"
+     */
+    private static final String PAR_LOGIN_AFTER_EXPIRE = null;
+
+    /**
+     * The default login after expire of a cookie.
+     *
+     * @see #PAR_LOGIN_AFTER_EXPIRE
+     */
+    private static final boolean DEFAULT_LOGIN_AFTER_EXPIRE = false;
+
+    /**
      * The request method required for user name and password submission by the
      * form (value is "POST").
      */
@@ -282,6 +297,11 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
      */
     private ResourceResolverFactory resourceResolverFactory;
 
+    /**
+     * If true the login form will be presented when the token expires.
+     */
+    private boolean loginAfterExpire;
+
 
     /**
      * Extracts cookie/session based credentials from the request. Returns
@@ -305,9 +325,11 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
                 if (tokenStore.isValid(authData)) {
                     info = createAuthInfo(authData);
                 } else {
-                    // signal the requestCredentials method a previous login failure
-                    request.setAttribute(PAR_J_REASON, FormReason.TIMEOUT);
-                    info = AuthenticationInfo.FAIL_AUTH;
+                    if (this.loginAfterExpire) {
+                      // 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
                     // isn't present on the authN operation.
                     authStorage.clear(request, response);
@@ -745,6 +767,8 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
 
         this.includeLoginForm = OsgiUtil.toBoolean(properties.get(PAR_INCLUDE_FORM), DEFAULT_INCLUDE_FORM);
 
+        this.loginAfterExpire = OsgiUtil.toBoolean(properties.get(PAR_LOGIN_AFTER_EXPIRE), DEFAULT_LOGIN_AFTER_EXPIRE);
+
     }
 
     protected void deactivate(

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 32/32: [maven-scm] copy for tag org.apache.sling.auth.form-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 637350c9ad84623e574a4306c42e875b26d2f1d2
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Aug 23 16:25:18 2010 +0000

    [maven-scm] copy for tag org.apache.sling.auth.form-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.auth.form-1.0.0@988182 13f79535-47bb-0310-9956-ffa450edef68

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 13/32: SLING-1116 Improve FormReason to convey the human-readable message by toString()

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 4e10552bdaf13b45fb1644585db4b375b3b56f76
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue Jun 22 07:31:44 2010 +0000

    SLING-1116 Improve FormReason to convey the human-readable message by toString()
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@956797 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/formauth/AuthenticationFormServlet.java  |  5 ++-
 .../sling/formauth/FormAuthenticationHandler.java  | 19 +++++------
 .../java/org/apache/sling/formauth/FormReason.java | 37 +++++++++++++---------
 .../org/apache/sling/formauth/FormReasonTest.java  |  4 +--
 4 files changed, 36 insertions(+), 29 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
index 34bed2b..0513205 100644
--- a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
@@ -144,10 +144,13 @@ public class AuthenticationFormServlet extends HttpServlet {
         final String reason = request.getParameter(FormAuthenticationHandler.PAR_J_REASON);
         if (reason != null) {
             try {
-                return FormReason.valueOf(reason).getMessage();
+                return FormReason.valueOf(reason).toString();
             } catch (IllegalArgumentException iae) {
                 // thrown if the reason is not an expected value, assume none
             }
+            
+            // no valid FormReason value, use raw value
+            return reason;
         }
 
         return "";
diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
index a8ca7ff..56849b5 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -58,22 +58,14 @@ import org.slf4j.LoggerFactory;
  *               value="Apache Sling Form Based Authentication Handler"
  * @scr.property name="service.vendor" value="The Apache Software Foundation"
  * @scr.property nameRef="AuthenticationHandler.PATH_PROPERTY" value="/"
+ * @scr.property nameRef="AuthenticationHandler.TYPE_PROPERTY" value="FORM"
+ *               private="true"
  * @scr.service
  */
 public class FormAuthenticationHandler implements AuthenticationHandler,
         AuthenticationFeedbackHandler {
 
     /**
-     * The request parameter causing a 401/UNAUTHORIZED status to be sent back
-     * in the {@link #authenticate(HttpServletRequest, HttpServletResponse)}
-     * method if no credentials are present in the request (value is
-     * "sling:authRequestLogin").
-     *
-     * @see #requestCredentials(HttpServletRequest, HttpServletResponse)
-     */
-    static final String REQUEST_LOGIN_PARAMETER = "sling:authRequestLogin";
-
-    /**
      * The name of the parameter providing the login form URL.
      *
      * @scr.property valueRef="AuthenticationFormServlet.SERVLET_PATH"
@@ -276,6 +268,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
                 } else {
                     // signal the requestCredentials method a previous login failure
                     request.setAttribute(PAR_J_REASON, FormReason.TIMEOUT);
+                    info = AuthenticationInfo.FAIL_AUTH;
                 }
             }
         }
@@ -337,7 +330,11 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
 
         // append indication of previous login failure
         if (request.getAttribute(PAR_J_REASON) != null) {
-            final String reason = String.valueOf(request.getAttribute(PAR_J_REASON));
+            final Object jReason = request.getAttribute(PAR_J_REASON);
+            @SuppressWarnings("unchecked")
+            final String reason = (jReason instanceof Enum)
+                    ? ((Enum) jReason).name()
+                    : jReason.toString();
             targetBuilder.append(parSep).append(PAR_J_REASON);
             targetBuilder.append("=").append(URLEncoder.encode(reason, "UTF-8"));
         }
diff --git a/src/main/java/org/apache/sling/formauth/FormReason.java b/src/main/java/org/apache/sling/formauth/FormReason.java
index 256e9e8..2b69869 100644
--- a/src/main/java/org/apache/sling/formauth/FormReason.java
+++ b/src/main/java/org/apache/sling/formauth/FormReason.java
@@ -24,27 +24,34 @@ enum FormReason {
      * The login form is request because the credentials previously entered very
      * not valid to login to the repository.
      */
-    INVALID_CREDENTIALS {
-        @Override
-        public String getMessage() {
-            return "Username and Password do not match";
-        }
-    },
+    INVALID_CREDENTIALS("Username and Password do not match"),
 
     /**
      * The login form is requested because an existing session has timed out and
      * the credentials have to be entered again.
      */
-    TIMEOUT {
-        @Override
-        public String getMessage() {
-            return "Session timed out, please login again";
-        }
-    };
+    TIMEOUT("Session timed out, please login again");
 
     /**
-     * Returns an english indicative message of the reason to request the login
-     * form.
+     * The user-friendly message returned by {@link #toString()}
      */
-    abstract String getMessage();
+    private final String message;
+
+    /**
+     * Creates an instance of the reason conveying the given descriptive reason.
+     *
+     * @param message The descriptive reason.
+     */
+    private FormReason(String message) {
+        this.message = message;
+    }
+
+    /**
+     * Returns the message set when constructing this instance. To get the
+     * official name call the <code>name()</code> method.
+     */
+    @Override
+    public String toString() {
+        return message;
+    }
 }
diff --git a/src/test/java/org/apache/sling/formauth/FormReasonTest.java b/src/test/java/org/apache/sling/formauth/FormReasonTest.java
index d723ef4..2db1617 100644
--- a/src/test/java/org/apache/sling/formauth/FormReasonTest.java
+++ b/src/test/java/org/apache/sling/formauth/FormReasonTest.java
@@ -24,12 +24,12 @@ public class FormReasonTest extends TestCase {
 
     public void test_TIMEOUT() {
         assertEquals(FormReason.TIMEOUT,
-            FormReason.valueOf(FormReason.TIMEOUT.toString()));
+            FormReason.valueOf(FormReason.TIMEOUT.name()));
     }
 
     public void test_INVALID_CREDENTIALS() {
         assertEquals(FormReason.INVALID_CREDENTIALS,
-            FormReason.valueOf(FormReason.INVALID_CREDENTIALS.toString()));
+            FormReason.valueOf(FormReason.INVALID_CREDENTIALS.name()));
     }
 
     public void test_INVALID() {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 25/32: SLING-1650 Consolidate authentication stuff in a new auth component; * rename commons/auth to auth/core * rename extensions/formauth to auth/form * rename extensions/openidauth to auth/openid

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit bdb95035ce10dda5a34ea5139ed63741443d8934
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Sun Aug 15 12:28:54 2010 +0000

    SLING-1650 Consolidate authentication stuff in a new auth component;
    * rename commons/auth to auth/core
    * rename extensions/formauth to auth/form
    * rename extensions/openidauth to auth/openid
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@985662 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/pom.xml b/pom.xml
index c5cf62d..edd5d28 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 
-    <artifactId>org.apache.sling.formauth</artifactId>
+    <artifactId>org.apache.sling.auth.form</artifactId>
     <version>0.9-SNAPSHOT</version>
     <packaging>bundle</packaging>
 
@@ -38,9 +38,9 @@
     </description>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/auth/form</url>
     </scm>
 
     <build>
@@ -59,10 +59,10 @@
                             http://sling.apache.org/site/form-based-authenticationhandler.html
                         </Bundle-DocURL>
                         <Export-Package>
-                            org.apache.sling.formauth;version=1.0
+                            org.apache.sling.auth.form;version=1.0
                         </Export-Package>
                         <Private-Package>
-                            org.apache.sling.formauth.impl.*
+                            org.apache.sling.auth.form.impl.*
                         </Private-Package>
                         <Import-Package>
                             javax.security.auth.callback;
@@ -96,7 +96,7 @@
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
                     <excludePackageNames>
-                        org.apache.sling.formauth
+                        org.apache.sling.auth.form
                     </excludePackageNames>
                 </configuration>
             </plugin>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 19/32: SLING-1575 Add @scr.service tag for login form servlets and fully qualify path property definition in the authentication handler

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 531e943282d397c0f249427b09c270ff18ebb427
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue Jul 27 14:13:39 2010 +0000

    SLING-1575 Add @scr.service tag for login form servlets and fully qualify path property definition in the authentication handler
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@979711 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/formauth/impl/AuthenticationFormServlet.java       |  1 +
 .../sling/formauth/impl/FormAuthenticationHandler.java       | 12 ++++++++----
 2 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
index a2c1d1b..1127f74 100644
--- a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
@@ -30,6 +30,7 @@ import org.apache.sling.formauth.FormReason;
  * @scr.property name="service.vendor" value="The Apache Software Foundation"
  * @scr.property name="service.description"
  *               value="Default Login Form for Form Based Authentication"
+ * @scr.service interface="javax.servlet.Servlet"
  */
 @SuppressWarnings("serial")
 public class AuthenticationFormServlet extends AbstractAuthenticationFormServlet {
diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index c902551..f92768d 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -55,8 +55,8 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * The <code>FormAuthenticationHandler</code> class implements the
- * authorization steps based on a cookie.
+ * The <code>FormAuthenticationHandler</code> class implements the authorization
+ * steps based on a cookie.
  *
  * @scr.component immediate="false" label="%auth.form.name"
  *                description="%auth.form.description"
@@ -64,8 +64,12 @@ import org.slf4j.LoggerFactory;
  * @scr.property name="service.description"
  *               value="Apache Sling Form Based Authentication Handler"
  * @scr.property name="service.vendor" value="The Apache Software Foundation"
- * @scr.property nameRef="AuthenticationHandler.PATH_PROPERTY" value="/"
- * @scr.property nameRef="AuthenticationHandler.TYPE_PROPERTY" value="FORM"
+ * @scr.property nameRef=
+ *               "org.apache.sling.commons.auth.spi.AuthenticationHandler.PATH_PROPERTY"
+ *               values.0="/"
+ * @scr.property nameRef=
+ *               "org.apache.sling.commons.auth.spi.AuthenticationHandler.TYPE_PROPERTY"
+ *               valueRef="javax.servlet.http.HttpServletRequest.FORM_AUTH"
  *               private="true"
  * @scr.service
  */

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 15/32: SLING-1565 - need to move the login form as well to be in the same package as the servlet

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit a606003392debc5534cae3dd0cf7c7c98c08d79f
Author: Justin Edelson <ju...@apache.org>
AuthorDate: Tue Jun 22 20:12:50 2010 +0000

    SLING-1565 - need to move the login form as well to be in the same package as the servlet
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@957007 13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/resources/org/apache/sling/formauth/{ => impl}/login.html | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/src/main/resources/org/apache/sling/formauth/login.html b/src/main/resources/org/apache/sling/formauth/impl/login.html
similarity index 100%
rename from src/main/resources/org/apache/sling/formauth/login.html
rename to src/main/resources/org/apache/sling/formauth/impl/login.html

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 04/32: SLING-1116 Fix service description

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 44c5ccdd278028138af0e5ec6f36fd671add16b8
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Thu Feb 11 08:14:31 2010 +0000

    SLING-1116 Fix service description
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@908866 13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
index 9dc5b30..5d8ed70 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -53,7 +53,7 @@ import org.slf4j.LoggerFactory;
  * @scr.component immediate="false" label="%auth.form.name"
  *                description="%auth.form.description"
  * @scr.property name="service.description"
- *               value="Cookie Based Authentication Handler"
+ *               value="Apache Sling Form Based Authentication Handler"
  * @scr.property name="service.vendor" value="The Apache Software Foundation"
  * @scr.property nameRef="AuthenticationHandler.PATH_PROPERTY" value="/"
  * @scr.service

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 23/32: SLING-1614 Added missing property name and metatype text.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit e561eda67452857f1cfeb08403d5bfa1317af040
Author: Ian Boston <ie...@apache.org>
AuthorDate: Wed Jul 28 16:00:01 2010 +0000

    SLING-1614 Added missing property name and metatype text.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@980108 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/formauth/impl/FormAuthenticationHandler.java   | 2 +-
 src/main/resources/OSGI-INF/metatype/metatype.properties            | 6 ++++++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index 4c100ce..197bcef 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -179,7 +179,7 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
      *
      * @scr.property type="Boolean" valueRef="DEFAULT_LOGIN_AFTER_EXPIRE"
      */
-    private static final String PAR_LOGIN_AFTER_EXPIRE = null;
+    private static final String PAR_LOGIN_AFTER_EXPIRE = "form.onexpire.login";
 
     /**
      * The default login after expire of a cookie.
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 2e5839e..686bd82 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -74,3 +74,9 @@ 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.
+
+form.onexpire.login.name = On Login Expire, Re-login
+form.onexpire.login.description = If true, when the form login expires the user \
+ will be prompted to re-login. If false they become an anonymous user. The default \
+ is false.
+ 
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 09/32: SLING-1498 - saving resource being requested

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 64b23944c56ea83b0b582fef33bafa4cf3318df8
Author: Justin Edelson <ju...@apache.org>
AuthorDate: Tue Apr 27 15:27:54 2010 +0000

    SLING-1498 - saving resource being requested
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@938516 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/formauth/FormAuthenticationHandler.java   | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
index 624aceb..75ec613 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -314,7 +314,11 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
 
         // append originally requested resource (for redirect after login)
         char parSep = '?';
-        final String resource = getLoginResource(request);
+        String resource = getLoginResource(request);
+        if (resource == null) {
+            resource = request.getContextPath() + request.getPathInfo();
+        }
+
         if (resource != null) {
             targetBuilder.append(parSep).append(Authenticator.LOGIN_RESOURCE);
             targetBuilder.append("=").append(

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 18/32: SLING-1575 Adapt Form and OpenID authentication handler to use new abstract form servlet and authentication handler

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit d3222a7e7e13176f6ba2b5965e62b9f743ab4ded
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue Jul 27 12:33:51 2010 +0000

    SLING-1575 Adapt Form and OpenID authentication handler to use new abstract form servlet and authentication handler
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@979669 13f79535-47bb-0310-9956-ffa450edef68
---
 .../formauth/impl/AuthenticationFormServlet.java   | 164 +--------------------
 .../formauth/impl/FormAuthenticationHandler.java   |  43 +-----
 2 files changed, 10 insertions(+), 197 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
index 233f48c..a2c1d1b 100644
--- a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
@@ -18,15 +18,8 @@
  */
 package org.apache.sling.formauth.impl;
 
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.Reader;
-
-import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
+import org.apache.sling.commons.auth.spi.AbstractAuthenticationFormServlet;
 import org.apache.sling.formauth.FormReason;
 
 /**
@@ -34,16 +27,15 @@ import org.apache.sling.formauth.FormReason;
  * used for Form Based Authentication.
  *
  * @scr.component metatype="no"
- * @scr.service interface="javax.servlet.Servlet"
  * @scr.property name="service.vendor" value="The Apache Software Foundation"
  * @scr.property name="service.description"
  *               value="Default Login Form for Form Based Authentication"
  */
 @SuppressWarnings("serial")
-public class AuthenticationFormServlet extends HttpServlet {
+public class AuthenticationFormServlet extends AbstractAuthenticationFormServlet {
 
     /**
-     * The constant is sued to provide the service registration path
+     * The constant is used to provide the service registration path
      *
      * @scr.property name="sling.servlet.paths"
      */
@@ -58,108 +50,6 @@ public class AuthenticationFormServlet extends HttpServlet {
     @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
-     * {@link #getRawForm()} method when first loading the form.
-     */
-    private volatile String rawForm;
-
-    /**
-     * 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 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();
-
-        // setup the response for HTML and cache prevention
-        response.setContentType("text/html");
-        response.setCharacterEncoding("UTF-8");
-        response.setHeader("Cache-Control", "no-cache");
-        response.addHeader("Cache-Control", "no-store");
-        response.setHeader("Pragma", "no-cache");
-        response.setHeader("Expires", "0");
-
-        // send the form and flush
-        response.getWriter().print(getForm(request));
-        response.flushBuffer();
-    }
-
-    /**
-     * Returns the form to be sent back to the client for login providing an
-     * optional informational message and the optional target to redirect to
-     * after successfully logging in.
-     *
-     * @param request The request providing parameters indicating the
-     *            informational message and redirection target.
-     * @return The login form to be returned to the client
-     * @throws IOException If the login form cannot be loaded
-     */
-    private String getForm(final HttpServletRequest request) throws IOException {
-        String form = getRawForm();
-
-        form = form.replace("${resource}", getResource(request));
-        form = form.replace("${j_reason}", getReason(request));
-        form = form.replace("${requestContextPath}", request.getContextPath());
-
-        return form;
-    }
-
-    /**
-     * Returns the path to the resource to which the request should be
-     * redirected after successfully completing the form or an empty string if
-     * there is no <code>resource</code> request parameter.
-     *
-     * @param request The request providing the <code>resource</code> parameter.
-     * @return The target to redirect after sucessfully login or an empty string
-     *         if no specific target has been requested.
-     */
-    private String getResource(final HttpServletRequest request) {
-        final String resource = FormAuthenticationHandler.getLoginResource(request);
-        return (resource == null) ? "" : resource;
-    }
-
     /**
      * Returns an informational message according to the value provided in the
      * <code>j_reason</code> request parameter. Supported reasons are invalid
@@ -169,7 +59,7 @@ public class AuthenticationFormServlet extends HttpServlet {
      * @return The "translated" reason to render the login form or an empty
      *         string if there is no specific reason
      */
-    private String getReason(final HttpServletRequest request) {
+    protected 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) {
@@ -190,50 +80,4 @@ public class AuthenticationFormServlet extends HttpServlet {
 
         return "";
     }
-
-    /**
-     * Load the raw unmodified form from the bundle (through the class loader).
-     *
-     * @return The raw form as a string
-     * @throws IOException If an error occurrs reading the "file" or if the
-     *             class loader cannot provide the form data.
-     */
-    private String getRawForm() throws IOException {
-        if (rawForm == null) {
-            InputStream ins = null;
-            try {
-                // 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");
-                    char[] cbuf = new char[1024];
-                    int rd = 0;
-                    while ((rd = r.read(cbuf)) >= 0) {
-                        builder.append(cbuf, 0, rd);
-                    }
-
-                    rawForm = builder.toString();
-                }
-            } finally {
-                if (ins != null) {
-                    try {
-                        ins.close();
-                    } catch (IOException ignore) {
-                    }
-                }
-            }
-
-            if (rawForm == null) {
-                throw new IOException("Failed reading form template");
-            }
-        }
-
-        return rawForm;
-    }
 }
diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index d62b5a0..c902551 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -37,13 +37,12 @@ import javax.servlet.http.HttpSession;
 
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.auth.Authenticator;
 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;
+import org.apache.sling.commons.auth.spi.AbstractAuthenticationHandler;
 import org.apache.sling.commons.auth.spi.AuthenticationInfo;
 import org.apache.sling.commons.auth.spi.DefaultAuthenticationFeedbackHandler;
 import org.apache.sling.commons.osgi.OsgiUtil;
@@ -70,8 +69,7 @@ import org.slf4j.LoggerFactory;
  *               private="true"
  * @scr.service
  */
-public class FormAuthenticationHandler implements AuthenticationHandler,
-        AuthenticationFeedbackHandler {
+public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
 
     /**
      * The name of the parameter providing the login form URL.
@@ -346,7 +344,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
             return true;
         }
 
-        String resource = getLoginResource(request);
+        String resource = getLoginResource(request, null);
         if (resource == null) {
             resource = request.getContextPath() + request.getPathInfo();
             request.setAttribute(Authenticator.LOGIN_RESOURCE, resource);
@@ -490,7 +488,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
 
             // check whether redirect is requested by the resource parameter
 
-            final String resource = getLoginResource(request);
+            final String resource = getLoginResource(request, null);
             if (resource != null) {
                 try {
                     response.sendRedirect(resource);
@@ -595,35 +593,6 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
         }
     }
 
-    /**
-     * Returns any resource target to redirect to after successful
-     * authentication. This method either returns a non-empty string or
-     * <code>null</code>. First the <code>resource</code> request attribute is
-     * checked. If it is a non-empty string, it is returned. Second the
-     * <code>resource</code> request parameter is checked and returned if it is
-     * a non-empty string.
-     *
-     * @param request The request providing the attribute or parameter
-     * @return The non-empty redirection target or <code>null</code>.
-     */
-    static String getLoginResource(final HttpServletRequest request) {
-
-        // return the resource attribute if set to a non-empty string
-        Object resObj = request.getAttribute(Authenticator.LOGIN_RESOURCE);
-        if ((resObj instanceof String) && ((String) resObj).length() > 0) {
-            return (String) resObj;
-        }
-
-        // return the resource parameter if not set or set to a non-empty value
-        final String resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
-        if (resource == null || resource.length() > 0) {
-            return resource;
-        }
-
-        // normalize empty resource string to null
-        return null;
-    }
-
     // --------- Request Parameter Auth ---------
 
     private AuthenticationInfo extractRequestParameterAuthentication(
@@ -647,7 +616,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
                 // 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) {
+                if (getLoginResource(request, null) == null) {
                     request.setAttribute(Authenticator.LOGIN_RESOURCE, "/");
                 }
             }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 14/32: SLING-1565 Move private implementation classes to the impl package and export the o.a.s.formauth package for login forms to be able to interpret the j_reason value with the FormReason enum.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 217e197a4c4fa3b83b733a25545432eae12c8c70
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue Jun 22 07:38:19 2010 +0000

    SLING-1565 Move private implementation classes to the impl package and export the o.a.s.formauth package for login forms to be able to interpret the j_reason value with the FormReason enum.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@956799 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                                             | 5 ++++-
 src/main/java/org/apache/sling/formauth/FormReason.java             | 2 +-
 .../apache/sling/formauth/{ => impl}/AuthenticationFormServlet.java | 4 +++-
 .../apache/sling/formauth/{ => impl}/FormAuthenticationHandler.java | 6 ++++--
 .../org/apache/sling/formauth/{ => impl}/FormLoginModulePlugin.java | 2 +-
 src/main/java/org/apache/sling/formauth/{ => impl}/TokenStore.java  | 2 +-
 .../sling/formauth/{ => impl}/FormAuthenticationHandlerTest.java    | 3 ++-
 7 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5666b0c..5202b4f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -59,8 +59,11 @@
                         <Bundle-DocURL>
                             http://sling.apache.org/site/form-based-authenticationhandler.html
                         </Bundle-DocURL>
+                        <Export-Package>
+                            org.apache.sling.formauth;version=1.0
+                        </Export-Package>
                         <Private-Package>
-                            org.apache.sling.formauth.*
+                            org.apache.sling.formauth.impl.*
                         </Private-Package>
                         <Import-Package>
                             javax.security.auth.callback;
diff --git a/src/main/java/org/apache/sling/formauth/FormReason.java b/src/main/java/org/apache/sling/formauth/FormReason.java
index 2b69869..4510a21 100644
--- a/src/main/java/org/apache/sling/formauth/FormReason.java
+++ b/src/main/java/org/apache/sling/formauth/FormReason.java
@@ -18,7 +18,7 @@
  */
 package org.apache.sling.formauth;
 
-enum FormReason {
+public enum FormReason {
 
     /**
      * The login form is request because the credentials previously entered very
diff --git a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
similarity index 98%
rename from src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
rename to src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
index 0513205..463f2de 100644
--- a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth;
+package org.apache.sling.formauth.impl;
 
 import java.io.IOException;
 import java.io.InputStream;
@@ -27,6 +27,8 @@ import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.sling.formauth.FormReason;
+
 /**
  * The <code>AuthenticationFormServlet</code> provides the default login form
  * used for Form Based Authentication.
diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
similarity index 99%
rename from src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
rename to src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index 56849b5..9e78e89 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth;
+package org.apache.sling.formauth.impl;
 
 import java.io.File;
 import java.io.IOException;
@@ -41,6 +41,7 @@ import org.apache.sling.commons.auth.spi.AuthenticationHandler;
 import org.apache.sling.commons.auth.spi.AuthenticationInfo;
 import org.apache.sling.commons.auth.spi.DefaultAuthenticationFeedbackHandler;
 import org.apache.sling.commons.osgi.OsgiUtil;
+import org.apache.sling.formauth.FormReason;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
@@ -49,11 +50,12 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * The <code>CookieAuthenticationHandler</code> class implements the
+ * The <code>FormAuthenticationHandler</code> class implements the
  * authorization steps based on a cookie.
  *
  * @scr.component immediate="false" label="%auth.form.name"
  *                description="%auth.form.description"
+ *                name="org.apache.sling.formauth.FormAuthenticationHandler"
  * @scr.property name="service.description"
  *               value="Apache Sling Form Based Authentication Handler"
  * @scr.property name="service.vendor" value="The Apache Software Foundation"
diff --git a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java b/src/main/java/org/apache/sling/formauth/impl/FormLoginModulePlugin.java
similarity index 99%
rename from src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
rename to src/main/java/org/apache/sling/formauth/impl/FormLoginModulePlugin.java
index b2776bf..79d9fa1 100644
--- a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormLoginModulePlugin.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth;
+package org.apache.sling.formauth.impl;
 
 import java.security.Principal;
 import java.util.Hashtable;
diff --git a/src/main/java/org/apache/sling/formauth/TokenStore.java b/src/main/java/org/apache/sling/formauth/impl/TokenStore.java
similarity index 99%
rename from src/main/java/org/apache/sling/formauth/TokenStore.java
rename to src/main/java/org/apache/sling/formauth/impl/TokenStore.java
index 390f1b2..2fe06ea 100644
--- a/src/main/java/org/apache/sling/formauth/TokenStore.java
+++ b/src/main/java/org/apache/sling/formauth/impl/TokenStore.java
@@ -15,7 +15,7 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.sling.formauth;
+package org.apache.sling.formauth.impl;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
diff --git a/src/test/java/org/apache/sling/formauth/FormAuthenticationHandlerTest.java b/src/test/java/org/apache/sling/formauth/impl/FormAuthenticationHandlerTest.java
similarity index 98%
rename from src/test/java/org/apache/sling/formauth/FormAuthenticationHandlerTest.java
rename to src/test/java/org/apache/sling/formauth/impl/FormAuthenticationHandlerTest.java
index 31e8e21..c0f6cff 100644
--- a/src/test/java/org/apache/sling/formauth/FormAuthenticationHandlerTest.java
+++ b/src/test/java/org/apache/sling/formauth/impl/FormAuthenticationHandlerTest.java
@@ -16,12 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth;
+package org.apache.sling.formauth.impl;
 
 import java.io.File;
 
 import junit.framework.TestCase;
 
+import org.apache.sling.formauth.impl.FormAuthenticationHandler;
 import org.hamcrest.Description;
 import org.hamcrest.text.StringStartsWith;
 import org.jmock.Expectations;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 12/32: Use released parent pom.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 6b812d80b6ec2168ec1ea168308a67a6cea28d98
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon May 17 13:42:29 2010 +0000

    Use released parent pom.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@945149 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 1305fb8..5666b0c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>8</version>
+        <version>9</version>
         <relativePath>../../../parent/pom.xml</relativePath>
     </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 31/32: [maven-release-plugin] prepare release org.apache.sling.auth.form-1.0.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 9e52b4e73cc7218fb52508d765ece1b825efb6d1
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Aug 23 16:24:28 2010 +0000

    [maven-release-plugin] prepare release org.apache.sling.auth.form-1.0.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@988181 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/pom.xml b/pom.xml
index 3352b28..2d3f6fe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,7 +26,7 @@
     </parent>
 
     <artifactId>org.apache.sling.auth.form</artifactId>
-    <version>0.9-SNAPSHOT</version>
+    <version>1.0.0</version>
     <packaging>bundle</packaging>
 
     <name>Apache Sling Form Based Authentication Handler</name>
@@ -43,9 +43,9 @@
     </properties>
 
     <scm>
-        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form</connection>
-        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form</developerConnection>
-        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/auth/form</url>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.auth.form-1.0.0</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.auth.form-1.0.0</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/tags/org.apache.sling.auth.form-1.0.0</url>
     </scm>
 
     <build>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 21/32: SLING-1588 Fixed, cookie needs to be removed when found to be invalid.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 99b10530e36e5c5c2dc52fd5cd6b468c4edfc06e
Author: Ian Boston <ie...@apache.org>
AuthorDate: Wed Jul 28 15:32:37 2010 +0000

    SLING-1588 Fixed, cookie needs to be removed when found to be invalid.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@980097 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index f92768d..638c04b 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -308,6 +308,9 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
                     // 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
+                    // isn't present on the authN operation.
+                    authStorage.clear(request, response);
                 }
             }
         }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 20/32: Remove unneeded (and commented out) version element

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 03ed695248a7eab732e57b6c97cfc9b395c9572e
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue Jul 27 14:34:56 2010 +0000

    Remove unneeded (and commented out) version element
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@979724 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 1c35467..c5cf62d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,7 +48,6 @@
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-scr-plugin</artifactId>
-<!--                <version>LATEST</version> -->
             </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 16/32: SLING-1564 - adding support for form inclusion as well as custom form pages via fragments

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit d5ecfb958c5cc603a89d7d3dd6421367fd2f4456
Author: Justin Edelson <ju...@apache.org>
AuthorDate: Wed Jun 23 21:30:55 2010 +0000

    SLING-1564 - adding support for form inclusion as well as custom form pages via fragments
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@957356 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            |  6 ++
 .../formauth/impl/AuthenticationFormServlet.java   | 43 ++++++++++++-
 .../formauth/impl/FormAuthenticationHandler.java   | 71 ++++++++++++++++++++--
 .../OSGI-INF/metatype/metatype.properties          | 16 +++--
 4 files changed, 124 insertions(+), 12 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5202b4f..1c35467 100644
--- a/pom.xml
+++ b/pom.xml
@@ -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>
diff --git a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
index 463f2de..233f48c 100644
--- a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
@@ -58,6 +58,10 @@ public class AuthenticationFormServlet extends HttpServlet {
     @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 extends HttpServlet {
     @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 extends HttpServlet {
      *         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 extends HttpServlet {
             } 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 extends HttpServlet {
         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");
diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index 9e78e89..1415c67 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -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 implements AuthenticationHandler,
     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 implements AuthenticationHandler,
     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 implements AuthenticationHandler,
             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 implements AuthenticationHandler,
 
         // 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 implements AuthenticationHandler,
             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(
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 3c2a922..2e5839e 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -31,7 +31,7 @@ path.description = Repository path for which this authentication handler \
  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 of storage used to provide the \
  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 of the file used to persist the \
 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.

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 10/32: SLING-1497 - adding tentative configuration for configuring service.ranking via ConfigAdmin/Metatype

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 0a8abcc1cc430e8fc557d9cf3b0a1a092c930f46
Author: Justin Edelson <ju...@apache.org>
AuthorDate: Tue Apr 27 15:28:03 2010 +0000

    SLING-1497 - adding tentative configuration for configuring service.ranking via ConfigAdmin/Metatype
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@938518 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                                          | 1 +
 .../org/apache/sling/formauth/FormAuthenticationHandler.java     | 9 +++++++++
 src/main/resources/OSGI-INF/metatype/metatype.properties         | 4 ++++
 3 files changed, 14 insertions(+)

diff --git a/pom.xml b/pom.xml
index 6623030..2b0ca7f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,6 +48,7 @@
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-scr-plugin</artifactId>
+                <version>LATEST</version>
             </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>
diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
index 75ec613..a8ca7ff 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -42,6 +42,7 @@ import org.apache.sling.commons.auth.spi.AuthenticationInfo;
 import org.apache.sling.commons.auth.spi.DefaultAuthenticationFeedbackHandler;
 import org.apache.sling.commons.osgi.OsgiUtil;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
@@ -207,6 +208,14 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
     static final String PAR_J_REASON = "j_reason";
 
     /**
+     * The service ranking property.
+     *
+     * @scr.property type="Integer" value="0" private="false"
+     */
+    @SuppressWarnings("unused")
+    private static final String PAR_SERVICE_RANKING = Constants.SERVICE_RANKING;
+
+    /**
      * The factor to convert minute numbers into milliseconds used internally
      */
     private static final long MINUTES = 60L * 1000L;
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 1dc9616..3c2a922 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -66,3 +66,7 @@ form.token.file.description = The name of the file used to persist the \
  sling.home framework property or - if sling.home is not set - the current \
  working directory. In the future this file may be store in the JCR Repository \
  to support clustering scenarios.
+
+service.ranking.name = Ranking
+service.ranking.description = The relative ranking of this service.
+

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 07/32: SLING-1116 make sure the login form action is an absolute path

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit a25ef67f80932570438206588c387ff61cc59895
Author: Eric Norman <en...@apache.org>
AuthorDate: Wed Feb 24 05:22:04 2010 +0000

    SLING-1116 make sure the login form action is an absolute path
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@915677 13f79535-47bb-0310-9956-ffa450edef68
---
 src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java | 1 +
 src/main/resources/org/apache/sling/formauth/login.html                | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
index d08016a..34bed2b 100644
--- a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
@@ -112,6 +112,7 @@ public class AuthenticationFormServlet extends HttpServlet {
 
         form = form.replace("${resource}", getResource(request));
         form = form.replace("${j_reason}", getReason(request));
+        form = form.replace("${requestContextPath}", request.getContextPath());
 
         return form;
     }
diff --git a/src/main/resources/org/apache/sling/formauth/login.html b/src/main/resources/org/apache/sling/formauth/login.html
index b9cb3d8..36d924d 100644
--- a/src/main/resources/org/apache/sling/formauth/login.html
+++ b/src/main/resources/org/apache/sling/formauth/login.html
@@ -58,7 +58,7 @@
 
 <div id="main"><!-- Login Form -->
 <h3>Login:</h3>
-<form id="loginform" method="POST" action="j_security_check"
+<form id="loginform" method="POST" action="${requestContextPath}/j_security_check"
         enctype="multipart/form-data" accept-charset="UTF-8">
 
    <input type="hidden" name="_charset_" value="UTF-8" />

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 26/32: SLING-1650 Refactor auth/core, auth/form, auth/openid for the new packages identifying the auth component and refer to the new auth/core for the authentication handlers.

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit f4f4bfcebf862a34b4c9e4fdf5eb987ce9cddbe1
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Aug 16 05:15:00 2010 +0000

    SLING-1650 Refactor auth/core, auth/form, auth/openid for the new packages identifying the auth component and refer to the new auth/core for the authentication handlers.
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@985787 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                                  |  2 +-
 .../apache/sling/{formauth => auth/form}/FormReason.java |  2 +-
 .../form}/impl/AuthenticationFormServlet.java            |  7 ++++---
 .../form}/impl/FormAuthenticationHandler.java            | 16 ++++++++--------
 .../form}/impl/FormLoginModulePlugin.java                |  2 +-
 .../sling/{formauth => auth/form}/impl/TokenStore.java   |  2 +-
 .../sling/{formauth => auth/form}/FormReasonTest.java    |  4 +++-
 .../form}/impl/FormAuthenticationHandlerTest.java        |  4 ++--
 8 files changed, 21 insertions(+), 18 deletions(-)

diff --git a/pom.xml b/pom.xml
index edd5d28..3a8132d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -105,7 +105,7 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.auth</artifactId>
+            <artifactId>org.apache.sling.auth.core</artifactId>
             <version>0.9.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
diff --git a/src/main/java/org/apache/sling/formauth/FormReason.java b/src/main/java/org/apache/sling/auth/form/FormReason.java
similarity index 98%
rename from src/main/java/org/apache/sling/formauth/FormReason.java
rename to src/main/java/org/apache/sling/auth/form/FormReason.java
index 4510a21..5405cea 100644
--- a/src/main/java/org/apache/sling/formauth/FormReason.java
+++ b/src/main/java/org/apache/sling/auth/form/FormReason.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth;
+package org.apache.sling.auth.form;
 
 public enum FormReason {
 
diff --git a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/auth/form/impl/AuthenticationFormServlet.java
similarity index 95%
rename from src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
rename to src/main/java/org/apache/sling/auth/form/impl/AuthenticationFormServlet.java
index 1127f74..2a38ff6 100644
--- a/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/auth/form/impl/AuthenticationFormServlet.java
@@ -16,11 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth.impl;
+package org.apache.sling.auth.form.impl;
 
 import javax.servlet.http.HttpServletRequest;
-import org.apache.sling.commons.auth.spi.AbstractAuthenticationFormServlet;
-import org.apache.sling.formauth.FormReason;
+
+import org.apache.sling.auth.core.spi.AbstractAuthenticationFormServlet;
+import org.apache.sling.auth.form.FormReason;
 
 /**
  * The <code>AuthenticationFormServlet</code> provides the default login form
diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
similarity index 98%
rename from src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
rename to src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
index 1e9663b..4322234 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/auth/form/impl/FormAuthenticationHandler.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth.impl;
+package org.apache.sling.auth.form.impl;
 
 import java.io.File;
 import java.io.IOException;
@@ -42,11 +42,11 @@ 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.spi.AbstractAuthenticationHandler;
-import org.apache.sling.commons.auth.spi.AuthenticationInfo;
-import org.apache.sling.commons.auth.spi.DefaultAuthenticationFeedbackHandler;
+import org.apache.sling.auth.core.spi.AbstractAuthenticationHandler;
+import org.apache.sling.auth.core.spi.AuthenticationInfo;
+import org.apache.sling.auth.core.spi.DefaultAuthenticationFeedbackHandler;
+import org.apache.sling.auth.form.FormReason;
 import org.apache.sling.commons.osgi.OsgiUtil;
-import org.apache.sling.formauth.FormReason;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceRegistration;
@@ -60,15 +60,15 @@ import org.slf4j.LoggerFactory;
  *
  * @scr.component immediate="false" label="%auth.form.name"
  *                description="%auth.form.description"
- *                name="org.apache.sling.formauth.FormAuthenticationHandler"
+ *                name="org.apache.sling.auth.form.FormAuthenticationHandler"
  * @scr.property name="service.description"
  *               value="Apache Sling Form Based Authentication Handler"
  * @scr.property name="service.vendor" value="The Apache Software Foundation"
  * @scr.property nameRef=
- *               "org.apache.sling.commons.auth.spi.AuthenticationHandler.PATH_PROPERTY"
+ *               "org.apache.sling.auth.core.spi.AuthenticationHandler.PATH_PROPERTY"
  *               values.0="/"
  * @scr.property nameRef=
- *               "org.apache.sling.commons.auth.spi.AuthenticationHandler.TYPE_PROPERTY"
+ *               "org.apache.sling.auth.core.spi.AuthenticationHandler.TYPE_PROPERTY"
  *               valueRef="javax.servlet.http.HttpServletRequest.FORM_AUTH"
  *               private="true"
  * @scr.service
diff --git a/src/main/java/org/apache/sling/formauth/impl/FormLoginModulePlugin.java b/src/main/java/org/apache/sling/auth/form/impl/FormLoginModulePlugin.java
similarity index 99%
rename from src/main/java/org/apache/sling/formauth/impl/FormLoginModulePlugin.java
rename to src/main/java/org/apache/sling/auth/form/impl/FormLoginModulePlugin.java
index 79d9fa1..786750b 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormLoginModulePlugin.java
+++ b/src/main/java/org/apache/sling/auth/form/impl/FormLoginModulePlugin.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth.impl;
+package org.apache.sling.auth.form.impl;
 
 import java.security.Principal;
 import java.util.Hashtable;
diff --git a/src/main/java/org/apache/sling/formauth/impl/TokenStore.java b/src/main/java/org/apache/sling/auth/form/impl/TokenStore.java
similarity index 99%
rename from src/main/java/org/apache/sling/formauth/impl/TokenStore.java
rename to src/main/java/org/apache/sling/auth/form/impl/TokenStore.java
index 2fe06ea..31a3977 100644
--- a/src/main/java/org/apache/sling/formauth/impl/TokenStore.java
+++ b/src/main/java/org/apache/sling/auth/form/impl/TokenStore.java
@@ -15,7 +15,7 @@
  * KIND, either express or implied. See the License for the
  * specific language governing permissions and limitations under the License.
  */
-package org.apache.sling.formauth.impl;
+package org.apache.sling.auth.form.impl;
 
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
diff --git a/src/test/java/org/apache/sling/formauth/FormReasonTest.java b/src/test/java/org/apache/sling/auth/form/FormReasonTest.java
similarity index 94%
rename from src/test/java/org/apache/sling/formauth/FormReasonTest.java
rename to src/test/java/org/apache/sling/auth/form/FormReasonTest.java
index 2db1617..4409621 100644
--- a/src/test/java/org/apache/sling/formauth/FormReasonTest.java
+++ b/src/test/java/org/apache/sling/auth/form/FormReasonTest.java
@@ -16,7 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth;
+package org.apache.sling.auth.form;
+
+import org.apache.sling.auth.form.FormReason;
 
 import junit.framework.TestCase;
 
diff --git a/src/test/java/org/apache/sling/formauth/impl/FormAuthenticationHandlerTest.java b/src/test/java/org/apache/sling/auth/form/impl/FormAuthenticationHandlerTest.java
similarity index 98%
rename from src/test/java/org/apache/sling/formauth/impl/FormAuthenticationHandlerTest.java
rename to src/test/java/org/apache/sling/auth/form/impl/FormAuthenticationHandlerTest.java
index c0f6cff..20f5054 100644
--- a/src/test/java/org/apache/sling/formauth/impl/FormAuthenticationHandlerTest.java
+++ b/src/test/java/org/apache/sling/auth/form/impl/FormAuthenticationHandlerTest.java
@@ -16,13 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.sling.formauth.impl;
+package org.apache.sling.auth.form.impl;
 
 import java.io.File;
 
 import junit.framework.TestCase;
 
-import org.apache.sling.formauth.impl.FormAuthenticationHandler;
+import org.apache.sling.auth.form.impl.FormAuthenticationHandler;
 import org.hamcrest.Description;
 import org.hamcrest.text.StringStartsWith;
 import org.jmock.Expectations;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 30/32: use Auth Core 1.0.0 to prepare the release

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit af26b77f7b6c4bed4f8444e918635611812535ab
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Aug 23 16:23:26 2010 +0000

    use Auth Core 1.0.0 to prepare the release
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@988180 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 33e10ec..3352b28 100644
--- a/pom.xml
+++ b/pom.xml
@@ -99,7 +99,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.auth.core</artifactId>
-            <version>0.9.0-SNAPSHOT</version>
+            <version>1.0.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 29/32: Update to Sling API 2.1.0

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit dc98910511b380db3f28ac629f8a18901cb9f5d4
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Aug 23 16:13:52 2010 +0000

    Update to Sling API 2.1.0
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@988173 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 7201953..33e10ec 100644
--- a/pom.xml
+++ b/pom.xml
@@ -111,7 +111,7 @@
         <dependency>
             <groupId>org.apache.sling</groupId>
             <artifactId>org.apache.sling.api</artifactId>
-            <version>2.0.9-SNAPSHOT</version>
+            <version>2.1.0</version>
             <scope>provided</scope>
         </dependency>
         <dependency>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 24/32: SLING-1647 Set handler specific properties in the AuthenticationInfo instead of the credentials. The properties will be transferred to the session by the ResourceResolverFactory implementation

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 008d39dfea7df5467fe34e12964ac28356ff68a4
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Thu Aug 12 13:52:24 2010 +0000

    SLING-1647 Set handler specific properties in the AuthenticationInfo instead of the credentials. The properties will be transferred to the session by the ResourceResolverFactory implementation
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@984778 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/formauth/impl/FormAuthenticationHandler.java   | 16 ++++++++++------
 1 file changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index 197bcef..1e9663b 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -592,7 +592,7 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
             final AuthenticationInfo authInfo) {
 
         // get current authentication data, may be missing after first login
-        String authData = getCookieAuthData((Credentials)authInfo.get(AuthenticationInfo.CREDENTIALS));
+        String authData = getCookieAuthData(authInfo);
 
         // check whether we have to "store" or create the data
         final boolean refreshCookie = needsRefresh(authData,
@@ -660,17 +660,21 @@ public class FormAuthenticationHandler extends AbstractAuthenticationHandler {
             return null;
         }
 
-        final SimpleCredentials cookieAuthCredentials = new SimpleCredentials(
-            userId, new char[0]);
-        cookieAuthCredentials.setAttribute(attrCookieAuthData, authData);
-
         final AuthenticationInfo info = new AuthenticationInfo(
             HttpServletRequest.FORM_AUTH, userId);
-        info.put(AuthenticationInfo.CREDENTIALS, cookieAuthCredentials);
+        info.put(attrCookieAuthData, authData);
 
         return info;
     }
 
+    private String getCookieAuthData(final AuthenticationInfo info) {
+        Object data = info.get(attrCookieAuthData);
+        if (data instanceof String) {
+            return (String) data;
+        }
+        return null;
+    }
+
     // ---------- LoginModulePlugin support
 
     private String getCookieAuthData(final Credentials credentials) {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 27/32: SLING-1650 Remove old packages; make sure the login.html form source is in the correct (new) location

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 5ba6c25cf25d8dc936556c4a5b75aea6b2f62270
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Aug 16 12:00:22 2010 +0000

    SLING-1650 Remove old packages; make sure the login.html form source is in the correct (new) location
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@985892 13f79535-47bb-0310-9956-ffa450edef68
---
 .../resources/org/apache/sling/{formauth => auth/form}/impl/login.html    | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

diff --git a/src/main/resources/org/apache/sling/formauth/impl/login.html b/src/main/resources/org/apache/sling/auth/form/impl/login.html
similarity index 100%
rename from src/main/resources/org/apache/sling/formauth/impl/login.html
rename to src/main/resources/org/apache/sling/auth/form/impl/login.html

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 03/32: SLING-1116 Implement support for the j_validate login form parameter and add support to convey a reason to render the login form using the j_reason request parameter for the login form request

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit a0fcd1a92f27be07f64d8e1fa3263b2e58c17d1b
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue Feb 9 10:24:13 2010 +0000

    SLING-1116 Implement support for the j_validate login form parameter and add support to convey a reason to render the login form using the j_reason request parameter for the login form request
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@907990 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/formauth/AuthenticationFormServlet.java  | 101 ++++++--
 .../sling/formauth/FormAuthenticationHandler.java  | 274 +++++++++++++++------
 .../java/org/apache/sling/formauth/FormReason.java |  50 ++++
 .../{ => org/apache/sling/formauth}/login.html     |  32 ++-
 .../org/apache/sling/formauth/FormReasonTest.java  |  43 ++++
 5 files changed, 410 insertions(+), 90 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
index 7c9f789..d08016a 100644
--- a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
+++ b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
@@ -23,13 +23,10 @@ import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.io.Reader;
 
-import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.sling.commons.auth.Authenticator;
-
 /**
  * The <code>AuthenticationFormServlet</code> provides the default login form
  * used for Form Based Authentication.
@@ -44,27 +41,54 @@ import org.apache.sling.commons.auth.Authenticator;
 public class AuthenticationFormServlet extends HttpServlet {
 
     /**
+     * The constant is sued to provide the service registration path
+     *
      * @scr.property name="sling.servlet.paths"
      */
     static final String SERVLET_PATH = "/system/sling/form/login";
 
     /**
+     * This constant is used to provide the service registration property
+     * indicating to pass requests to this servlet unauthenticated.
+     *
      * @scr.property name="sling.auth.requirements"
      */
     @SuppressWarnings("unused")
     private static final String AUTH_REQUIREMENT = "-" + SERVLET_PATH;
 
+    /**
+     * The raw form used by the {@link #getForm(HttpServletRequest)} method to
+     * fill in with per-request data. This field is set by the
+     * {@link #getRawForm()} method when first loading the form.
+     */
     private volatile String rawForm;
 
+    /**
+     * 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 doGet(HttpServletRequest request,
             HttpServletResponse response) throws IOException {
 
+        // reset the response first
+        response.reset();
+
         // setup the response for HTML and cache prevention
         response.setContentType("text/html");
         response.setCharacterEncoding("UTF-8");
-        response.setHeader("Cache-control", "no-cache");
-        response.addHeader("Cache-control", "no-store");
+        response.setHeader("Cache-Control", "no-cache");
+        response.addHeader("Cache-Control", "no-store");
         response.setHeader("Pragma", "no-cache");
         response.setHeader("Expires", "0");
 
@@ -73,30 +97,73 @@ public class AuthenticationFormServlet extends HttpServlet {
         response.flushBuffer();
     }
 
-    @Override
-    protected void doPost(HttpServletRequest request,
-            HttpServletResponse response) throws ServletException, IOException {
-        super.doPost(request, response);
+    /**
+     * Returns the form to be sent back to the client for login providing an
+     * optional informational message and the optional target to redirect to
+     * after successfully logging in.
+     *
+     * @param request The request providing parameters indicating the
+     *            informational message and redirection target.
+     * @return The login form to be returned to the client
+     * @throws IOException If the login form cannot be loaded
+     */
+    private String getForm(final HttpServletRequest request) throws IOException {
+        String form = getRawForm();
+
+        form = form.replace("${resource}", getResource(request));
+        form = form.replace("${j_reason}", getReason(request));
+
+        return form;
     }
 
-    private String getForm(final HttpServletRequest request) throws IOException {
+    /**
+     * Returns the path to the resource to which the request should be
+     * redirected after successfully completing the form or an empty string if
+     * there is no <code>resource</code> request parameter.
+     *
+     * @param request The request providing the <code>resource</code> parameter.
+     * @return The target to redirect after sucessfully login or an empty string
+     *         if no specific target has been requested.
+     */
+    private String getResource(final HttpServletRequest request) {
+        final String resource = FormAuthenticationHandler.getLoginResource(request);
+        return (resource == null) ? "" : resource;
+    }
 
-        String resource = (String) request.getAttribute(Authenticator.LOGIN_RESOURCE);
-        if (resource == null) {
-            resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
-            if (resource == null) {
-                resource = "/";
+    /**
+     * Returns an informational message according to the value provided in the
+     * <code>j_reason</code> request parameter. Supported reasons are invalid
+     * credentials and session timeout.
+     *
+     * @param request The request providing the parameter
+     * @return The "translated" reason to render the login form or an empty
+     *         string if there is no specific reason
+     */
+    private String getReason(final HttpServletRequest request) {
+        final String reason = request.getParameter(FormAuthenticationHandler.PAR_J_REASON);
+        if (reason != null) {
+            try {
+                return FormReason.valueOf(reason).getMessage();
+            } catch (IllegalArgumentException iae) {
+                // thrown if the reason is not an expected value, assume none
             }
         }
 
-        return getRawForm().replace("${resource}", resource);
+        return "";
     }
 
+    /**
+     * Load the raw unmodified form from the bundle (through the class loader).
+     *
+     * @return The raw form as a string
+     * @throws IOException If an error occurrs reading the "file" or if the
+     *             class loader cannot provide the form data.
+     */
     private String getRawForm() throws IOException {
         if (rawForm == null) {
             InputStream ins = null;
             try {
-                ins = getClass().getResourceAsStream("/login.html");
+                ins = getClass().getResourceAsStream("login.html");
                 if (ins != null) {
                     StringBuilder builder = new StringBuilder();
                     Reader r = new InputStreamReader(ins, "UTF-8");
diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
index c135cc4..9dc5b30 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -190,11 +190,26 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
     private static final String PAR_J_PASSWORD = "j_password";
 
     /**
+     * The name of the form submission parameter indicating that the submitted
+     * username and password should just be checked and a status code be set for
+     * success (200/OK) or failure (403/FORBIDDEN).
+     */
+    private static final String PAR_J_VALIDATE = "j_validate";
+
+    /**
+     * The name of the request parameter indicating to the login form why the
+     * form is being rendered. If this parameter is not set the form is called
+     * for the first time and the implied reason is that the authenticator just
+     * requests credentials. Otherwise the parameter is set to a
+     * {@link FormReason} value.
+     */
+    static final String PAR_J_REASON = "j_reason";
+
+    /**
      * The factor to convert minute numbers into milliseconds used internally
      */
     private static final long MINUTES = 60L * 1000L;
 
-
     /** default log */
     private final Logger log = LoggerFactory.getLogger(getClass());
 
@@ -231,43 +246,75 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
         // 2. try credentials from the cookie or session
         if (info == null) {
             String authData = authStorage.extractAuthenticationInfo(request);
-            if (authData != null && tokenStore.isValid(authData)) {
-                info = createAuthInfo(authData);
+            if (authData != null) {
+                if (tokenStore.isValid(authData)) {
+                    info = createAuthInfo(authData);
+                } else {
+                    // signal the requestCredentials method a previous login failure
+                    request.setAttribute(PAR_J_REASON, FormReason.TIMEOUT);
+                }
             }
         }
 
         return info;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see
-     * org.apache.sling.commons.auth.spi.AuthenticationHandler#requestCredentials
-     * (javax.servlet.http.HttpServletRequest,
-     * javax.servlet.http.HttpServletResponse)
+    /**
+     * Unless the <code>sling:authRequestLogin</code> to anything other than
+     * <code>Form</code> this method either sends back a 403/FORBIDDEN response
+     * if the <code>j_verify</code> parameter is set to <code>true</code> or
+     * redirects to the login form to ask for credentials.
+     * <p>
+     * This method assumes the <code>j_verify</code> request parameter to only
+     * be set in the initial username/password submission through the login
+     * form. No further checks are applied, though, before sending back the
+     * 403/FORBIDDEN response.
      */
     public boolean requestCredentials(HttpServletRequest request,
             HttpServletResponse response) throws IOException {
 
         // 0. ignore this handler if an authentication handler is requested
         if (ignoreRequestCredentials(request)) {
+            // consider this handler is not used
             return false;
         }
 
-        String resource = (String) request.getAttribute(Authenticator.LOGIN_RESOURCE);
-        if (resource == null || resource.length() == 0) {
-            resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
-            if (resource == null || resource.length() == 0) {
-                resource = request.getRequestURI();
+        // 1. check whether we short cut for a failed log in with validation
+        if (isValidateRequest(request)) {
+            try {
+                response.setStatus(403);
+                response.flushBuffer();
+            } catch (IOException ioe) {
+                log.error("Failed to send 403/FORBIDDEN response", ioe);
             }
+
+            // consider credentials requested
+            return true;
         }
 
+        // prepare the login form redirection target
         final StringBuilder targetBuilder = new StringBuilder();
         targetBuilder.append(request.getContextPath());
         targetBuilder.append(loginForm);
-        targetBuilder.append('?').append(Authenticator.LOGIN_RESOURCE);
-        targetBuilder.append("=").append(URLEncoder.encode(resource, "UTF-8"));
 
+        // append originally requested resource (for redirect after login)
+        char parSep = '?';
+        final String resource = getLoginResource(request);
+        if (resource != null) {
+            targetBuilder.append(parSep).append(Authenticator.LOGIN_RESOURCE);
+            targetBuilder.append("=").append(
+                URLEncoder.encode(resource, "UTF-8"));
+            parSep = '&';
+        }
+
+        // append indication of previous login failure
+        if (request.getAttribute(PAR_J_REASON) != null) {
+            final String reason = String.valueOf(request.getAttribute(PAR_J_REASON));
+            targetBuilder.append(parSep).append(PAR_J_REASON);
+            targetBuilder.append("=").append(URLEncoder.encode(reason, "UTF-8"));
+        }
+
+        // finally redirect to the login form
         final String target = targetBuilder.toString();
         try {
             response.sendRedirect(target);
@@ -278,30 +325,13 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
         return true;
     }
 
-    /*
-     * (non-Javadoc)
-     * @see
-     * org.apache.sling.commons.auth.spi.AuthenticationHandler#dropCredentials
-     * (javax.servlet.http.HttpServletRequest,
-     * javax.servlet.http.HttpServletResponse)
+    /**
+     * Clears all authentication state which might have been prepared by this
+     * authentication handler.
      */
     public void dropCredentials(HttpServletRequest request,
             HttpServletResponse response) {
-
         authStorage.clear(request, response);
-
-        // if there is a referer header, redirect back there
-        // with an anonymous session
-        String referer = request.getHeader("referer");
-        if (referer == null) {
-            referer = request.getContextPath() + "/";
-        }
-
-        try {
-            response.sendRedirect(referer);
-        } catch (IOException e) {
-            log.error("Failed to redirect to the page: " + referer, e);
-        }
     }
 
     // ---------- AuthenticationFeedbackHandler
@@ -313,7 +343,17 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
      */
     public void authenticationFailed(HttpServletRequest request,
             HttpServletResponse response, AuthenticationInfo authInfo) {
+
+        /*
+         * Note: This method is called if this handler provided credentials
+         * which cause a login failure
+         */
+
+        // clear authentication data from Cookie or Http Session
         authStorage.clear(request, response);
+
+        // signal the requestCredentials method a previous login failure
+        request.setAttribute(PAR_J_REASON, FormReason.INVALID_CREDENTIALS);
     }
 
     /**
@@ -332,55 +372,56 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
     public boolean authenticationSucceeded(HttpServletRequest request,
             HttpServletResponse response, AuthenticationInfo authInfo) {
 
-        // get current authentication data, may be missing after first login
-        String authData = getCookieAuthData(authInfo.getCredentials());
+        /*
+         * Note: This method is called if this handler provided credentials
+         * which succeeded loging into the repository
+         */
 
-        // check whether we have to "store" or create the data
-        final boolean refreshCookie = needsRefresh(authData,
-            this.sessionTimeout);
+        // ensure fresh authentication data
+        refreshAuthData(request, response, authInfo);
+
+        final boolean result;
+        if (isValidateRequest(request)) {
 
-        // add or refresh the stored auth hash
-        if (refreshCookie) {
-            long expires = System.currentTimeMillis() + this.sessionTimeout;
             try {
-                authData = null;
-                authData = tokenStore.encode(expires, authInfo.getUser());
-            } catch (InvalidKeyException e) {
-                log.error(e.getMessage(), e);
-            } catch (IllegalStateException e) {
-                log.error(e.getMessage(), e);
-            } catch (UnsupportedEncodingException e) {
-                log.error(e.getMessage(), e);
-            } catch (NoSuchAlgorithmException e) {
-                log.error(e.getMessage(), e);
+                response.setStatus(200);
+                response.flushBuffer();
+            } catch (IOException ioe) {
+                log.error("Failed to send 200/OK response", ioe);
             }
 
-            if (authData != null) {
-                authStorage.set(request, response, authData);
-            } else {
-                authStorage.clear(request, response);
-            }
-        }
+            // terminate request, all done
+            result = true;
 
-        if (!DefaultAuthenticationFeedbackHandler.handleRedirect(request,
-            response)) {
+        } else if (DefaultAuthenticationFeedbackHandler.handleRedirect(
+            request, response)) {
 
-            String resource = (String) request.getAttribute(Authenticator.LOGIN_RESOURCE);
-            if (resource == null || resource.length() == 0) {
-                resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
-            }
-            if (resource != null && resource.length() > 0) {
+            // terminate request, all done in the default handler
+            result = false;
+
+        } else {
+
+            // check whether redirect is requested by the resource parameter
+
+            final String resource = getLoginResource(request);
+            if (resource != null) {
                 try {
                     response.sendRedirect(resource);
                 } catch (IOException ioe) {
+                    log.error("Failed to send redirect to: " + resource, ioe);
                 }
-                return true;
+
+                // terminate request, all done
+                result = true;
+            } else {
+                // no redirect, hence continue processing
+                result = false;
             }
 
         }
 
         // no redirect
-        return false;
+        return result;
     }
 
     @Override
@@ -399,12 +440,103 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
      * {@link #REQUEST_LOGIN_PARAMETER} is set to any value other than "Form"
      * (HttpServletRequest.FORM_AUTH).
      */
-    private boolean ignoreRequestCredentials(HttpServletRequest request) {
+    private boolean ignoreRequestCredentials(final HttpServletRequest request) {
         final String requestLogin = request.getParameter(REQUEST_LOGIN_PARAMETER);
         return requestLogin != null
             && !HttpServletRequest.FORM_AUTH.equals(requestLogin);
     }
 
+    /**
+     * Returns <code>true</code> if the the client just asks for validation of
+     * submitted username/password credentials.
+     * <p>
+     * This implementation returns <code>true</code> if the request parameter
+     * {@link #PAR_J_VALIDATE} is set to <code>true</code> (case-insensitve). If
+     * the request parameter is not set or to any value other than
+     * <code>true</code> this method returns <code>false</code>.
+     *
+     * @param request The request to provide the parameter to check
+     * @return <code>true</code> if the {@link #PAR_J_VALIDATE} parameter is set
+     *         to <code>true</code>.
+     */
+    private boolean isValidateRequest(final HttpServletRequest request) {
+        return "true".equalsIgnoreCase(request.getParameter(PAR_J_VALIDATE));
+    }
+
+    /**
+     * Ensures the authentication data is set (if not set yet) and the expiry
+     * time is prolonged (if auth data already existed).
+     * <p>
+     * This method is intended to be called in case authentication succeeded.
+     *
+     * @param request The curent request
+     * @param response The current response
+     * @param authInfo The authentication info used to successfull log in
+     */
+    private void refreshAuthData(final HttpServletRequest request,
+            final HttpServletResponse response,
+            final AuthenticationInfo authInfo) {
+
+        // get current authentication data, may be missing after first login
+        String authData = getCookieAuthData(authInfo.getCredentials());
+
+        // check whether we have to "store" or create the data
+        final boolean refreshCookie = needsRefresh(authData,
+            this.sessionTimeout);
+
+        // add or refresh the stored auth hash
+        if (refreshCookie) {
+            long expires = System.currentTimeMillis() + this.sessionTimeout;
+            try {
+                authData = null;
+                authData = tokenStore.encode(expires, authInfo.getUser());
+            } catch (InvalidKeyException e) {
+                log.error(e.getMessage(), e);
+            } catch (IllegalStateException e) {
+                log.error(e.getMessage(), e);
+            } catch (UnsupportedEncodingException e) {
+                log.error(e.getMessage(), e);
+            } catch (NoSuchAlgorithmException e) {
+                log.error(e.getMessage(), e);
+            }
+
+            if (authData != null) {
+                authStorage.set(request, response, authData);
+            } else {
+                authStorage.clear(request, response);
+            }
+        }
+    }
+
+    /**
+     * Returns any resource target to redirect to after successful
+     * authentication. This method either returns a non-empty string or
+     * <code>null</code>. First the <code>resource</code> request attribute is
+     * checked. If it is a non-empty string, it is returned. Second the
+     * <code>resource</code> request parameter is checked and returned if it is
+     * a non-empty string.
+     *
+     * @param request The request providing the attribute or parameter
+     * @return The non-empty redirection target or <code>null</code>.
+     */
+    static String getLoginResource(final HttpServletRequest request) {
+
+        // return the resource attribute if set to a non-empty string
+        Object resObj = request.getAttribute(Authenticator.LOGIN_RESOURCE);
+        if ((resObj instanceof String) && ((String) resObj).length() > 0) {
+            return (String) resObj;
+        }
+
+        // return the resource parameter if not set or set to a non-empty value
+        final String resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
+        if (resource == null || resource.length() > 0) {
+            return resource;
+        }
+
+        // normalize empty resource string to null
+        return null;
+    }
+
     // --------- Request Parameter Auth ---------
 
     private AuthenticationInfo extractRequestParameterAuthentication(
@@ -419,7 +551,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
             String user = request.getParameter(PAR_J_USERNAME);
             String pwd = request.getParameter(PAR_J_PASSWORD);
 
-            if (user != null && user.length() > 0 && pwd != null) {
+            if (user != null && pwd != null) {
                 info = new AuthenticationInfo(HttpServletRequest.FORM_AUTH,
                     user, pwd.toCharArray());
             }
diff --git a/src/main/java/org/apache/sling/formauth/FormReason.java b/src/main/java/org/apache/sling/formauth/FormReason.java
new file mode 100644
index 0000000..256e9e8
--- /dev/null
+++ b/src/main/java/org/apache/sling/formauth/FormReason.java
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.formauth;
+
+enum FormReason {
+
+    /**
+     * The login form is request because the credentials previously entered very
+     * not valid to login to the repository.
+     */
+    INVALID_CREDENTIALS {
+        @Override
+        public String getMessage() {
+            return "Username and Password do not match";
+        }
+    },
+
+    /**
+     * The login form is requested because an existing session has timed out and
+     * the credentials have to be entered again.
+     */
+    TIMEOUT {
+        @Override
+        public String getMessage() {
+            return "Session timed out, please login again";
+        }
+    };
+
+    /**
+     * Returns an english indicative message of the reason to request the login
+     * form.
+     */
+    abstract String getMessage();
+}
diff --git a/src/main/resources/login.html b/src/main/resources/org/apache/sling/formauth/login.html
similarity index 58%
rename from src/main/resources/login.html
rename to src/main/resources/org/apache/sling/formauth/login.html
index 2d3c7a0..b9cb3d8 100644
--- a/src/main/resources/login.html
+++ b/src/main/resources/org/apache/sling/formauth/login.html
@@ -1,4 +1,24 @@
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+
+      Licensed to the Apache Software Foundation (ASF) under one
+      or more contributor license agreements.  See the NOTICE file
+      distributed with this work for additional information
+      regarding copyright ownership.  The ASF licenses this file
+      to you under the Apache License, Version 2.0 (the
+      "License"); you may not use this file except in compliance
+      with the License.  You may obtain a copy of the License at
+     
+        http://www.apache.org/licenses/LICENSE-2.0
+     
+      Unless required by applicable law or agreed to in writing,
+      software distributed under the License is distributed on an
+      "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+      KIND, either express or implied.  See the License for the
+      specific language governing permissions and limitations
+      under the License.
+
+-->
 <html xml:lang="en" lang="en"
       xmlns="http://www.w3.org/1999/xhtml"
 >
@@ -26,6 +46,10 @@
        padding: 0px;
        margin: 0px;
    }
+   
+   #err {
+       color: red;
+   }
    </style>
    
 </head>
@@ -39,9 +63,13 @@
 
    <input type="hidden" name="_charset_" value="UTF-8" />
    <input type="hidden" name="resource" value="${resource}" />
-   
+
+   <div id="err">
+      <p>${j_reason}</p>
+   </div>
+      
    <div>
-      <label for="j_username" accesskey="u">User ID:</label>
+      <label for="j_username" accesskey="u">Username:</label>
    </div>
    <div>
       <input id="j_username" name="j_username" type="text" />
diff --git a/src/test/java/org/apache/sling/formauth/FormReasonTest.java b/src/test/java/org/apache/sling/formauth/FormReasonTest.java
new file mode 100644
index 0000000..d723ef4
--- /dev/null
+++ b/src/test/java/org/apache/sling/formauth/FormReasonTest.java
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.formauth;
+
+import junit.framework.TestCase;
+
+public class FormReasonTest extends TestCase {
+
+    public void test_TIMEOUT() {
+        assertEquals(FormReason.TIMEOUT,
+            FormReason.valueOf(FormReason.TIMEOUT.toString()));
+    }
+
+    public void test_INVALID_CREDENTIALS() {
+        assertEquals(FormReason.INVALID_CREDENTIALS,
+            FormReason.valueOf(FormReason.INVALID_CREDENTIALS.toString()));
+    }
+
+    public void test_INVALID() {
+        try {
+            FormReason.valueOf("INVALID");
+            fail("unexpected result getting value of an invalid constant");
+        } catch (IllegalArgumentException iae) {
+            // expected
+        }
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 08/32: SLING-1419 : Remove dependency to JCR

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 33e89b6159e4cd82ea0ff9b9e6642c36cbe9dbee
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sat Mar 6 19:28:25 2010 +0000

    SLING-1419 : Remove dependency to JCR
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@919825 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/formauth/FormAuthenticationHandler.java     | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
index eedca08..624aceb 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -493,7 +493,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
             final AuthenticationInfo authInfo) {
 
         // get current authentication data, may be missing after first login
-        String authData = getCookieAuthData(authInfo.getCredentials());
+        String authData = getCookieAuthData((Credentials)authInfo.get(AuthenticationInfo.CREDENTIALS));
 
         // check whether we have to "store" or create the data
         final boolean refreshCookie = needsRefresh(authData,
@@ -596,7 +596,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
 
         final AuthenticationInfo info = new AuthenticationInfo(
             HttpServletRequest.FORM_AUTH, userId);
-        info.setCredentials(cookieAuthCredentials);
+        info.put(AuthenticationInfo.CREDENTIALS, cookieAuthCredentials);
 
         return info;
     }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 06/32: SLING-1380 Do not return anything from getPrincipal to allow DefaultLoginModule.getPrincipal to kick in and validate the user name against the existing users (and also to provide the correct principal for the user)

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 0a41f41e4aeab80e25d4a91c6b4f1510f36ed360
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Tue Feb 16 12:22:01 2010 +0000

    SLING-1380 Do not return anything from getPrincipal to allow DefaultLoginModule.getPrincipal to kick in and validate the user name against the existing users (and also to provide the correct principal for the user)
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@910496 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/formauth/FormLoginModulePlugin.java   | 14 ++------------
 1 file changed, 2 insertions(+), 12 deletions(-)

diff --git a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
index 31ee174..b2776bf 100644
--- a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
+++ b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
@@ -25,7 +25,6 @@ import java.util.Set;
 
 import javax.jcr.Credentials;
 import javax.jcr.Session;
-import javax.jcr.SimpleCredentials;
 import javax.security.auth.callback.CallbackHandler;
 import org.apache.sling.jcr.jackrabbit.server.security.AuthenticationPlugin;
 import org.apache.sling.jcr.jackrabbit.server.security.LoginModulePlugin;
@@ -114,19 +113,10 @@ final class FormLoginModulePlugin implements LoginModulePlugin {
     }
 
     /**
-     * Returns a simple <code>Principal</code> just providing the user id
-     * contained in the <code>SimpleCredentials</code> object. If the
-     * credentials is not a <code>SimpleCredentials</code> instance,
-     * <code>null</code> is returned.
+     * Returns <code>null</code> to have the <code>DefaultLoginModule</code>
+     * provide a principal based on an existing user defined in the repository.
      */
     public Principal getPrincipal(final Credentials credentials) {
-        if (credentials instanceof SimpleCredentials) {
-            return new Principal() {
-                public String getName() {
-                    return ((SimpleCredentials) credentials).getUserID();
-                }
-            };
-        }
         return null;
     }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 11/32: forgot that maven 3 dropped support for latest. oh well, new scr plugin should be released rsn

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 1cb242e8b48c0b77931338cccb72019b4f840a35
Author: Justin Edelson <ju...@apache.org>
AuthorDate: Wed Apr 28 13:27:53 2010 +0000

    forgot that maven 3 dropped support for latest. oh well, new scr plugin should be released rsn
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@938977 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 2b0ca7f..1305fb8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -48,7 +48,7 @@
             <plugin>
                 <groupId>org.apache.felix</groupId>
                 <artifactId>maven-scr-plugin</artifactId>
-                <version>LATEST</version>
+<!--                <version>LATEST</version> -->
             </plugin>
             <plugin>
                 <groupId>org.apache.felix</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 02/32: SLING-1116 cleanup dependencies

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 8b679bf25086eb24ef5bb51a9285658129792096
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Feb 8 15:19:35 2010 +0000

    SLING-1116 cleanup dependencies
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@907686 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            | 55 +++++++++-------------
 .../sling/formauth/FormLoginModulePlugin.java      |  2 +-
 2 files changed, 23 insertions(+), 34 deletions(-)

diff --git a/pom.xml b/pom.xml
index 5732e73..6623030 100644
--- a/pom.xml
+++ b/pom.xml
@@ -102,29 +102,40 @@
     <dependencies>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.api</artifactId>
-            <version>2.0.8</version>
+            <artifactId>org.apache.sling.commons.auth</artifactId>
+            <version>0.9.0-SNAPSHOT</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <artifactId>org.apache.sling.jcr.jackrabbit.server</artifactId>
             <version>2.0.4-incubator</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.engine</artifactId>
-            <version>2.0.6</version>
-            <scope>provided</scope>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
         </dependency>
         <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+
+        <!-- Embedded Dependencies -->
+        <dependency>
             <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.commons.auth</artifactId>
-            <version>0.9.0-SNAPSHOT</version>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.0.2-incubator</version>
             <scope>provided</scope>
         </dependency>
-
         <dependency>
             <groupId>commons-codec</groupId>
             <artifactId>commons-codec</artifactId>
@@ -138,29 +149,7 @@
             <scope>provided</scope>
         </dependency>
 
-        <dependency>
-            <groupId>org.apache.sling</groupId>
-            <artifactId>org.apache.sling.jcr.jackrabbit.server</artifactId>
-            <version>2.0.5-SNAPSHOT</version>
-            <scope>provided</scope>
-        </dependency>
-
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.core</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.osgi</groupId>
-            <artifactId>org.osgi.compendium</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>javax.servlet</groupId>
-            <artifactId>servlet-api</artifactId>
-        </dependency>
-        <dependency>
-            <groupId>org.slf4j</groupId>
-            <artifactId>slf4j-api</artifactId>
-        </dependency>
+        <!-- Test Dependencies -->
         <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
diff --git a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
index e4b60dd..6e95be2 100644
--- a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
+++ b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
@@ -77,7 +77,7 @@ final class FormLoginModulePlugin implements LoginModulePlugin {
      * This implementation does nothing.
      */
     @SuppressWarnings("unchecked")
-    public void addPrincipals(Set principals) {
+    public void addPrincipals(@SuppressWarnings("unused") Set principals) {
     }
 
     /**

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 17/32: SLING-1587 - file name wasn't being logged

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 196a11f0321d7f56cfdeda54fc6fb2605ec6aaa5
Author: Justin Edelson <ju...@apache.org>
AuthorDate: Mon Jul 5 17:47:55 2010 +0000

    SLING-1587 - file name wasn't being logged
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@960651 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java  | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
index 1415c67..d62b5a0 100644
--- a/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
@@ -755,7 +755,7 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
             properties.get(PAR_TOKEN_FILE), DEFAULT_TOKEN_FILE);
         final File tokenFile = getTokenFile(tokenFileName,
             componentContext.getBundleContext());
-        log.info("Storing tokens in ", tokenFile);
+        log.info("Storing tokens in {}", tokenFile.getAbsolutePath());
         this.tokenStore = new TokenStore(tokenFile, sessionTimeout);
 
         this.loginModule = null;

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 01/32: SLING-1116 Initial Version based on Eric Norman's patch (thanks alot)

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit f467e0e07080495017136469d0dac42c7df2266e
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Feb 8 15:08:38 2010 +0000

    SLING-1116 Initial Version based on Eric Norman's patch (thanks alot)
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@907677 13f79535-47bb-0310-9956-ffa450edef68
---
 README.txt                                         |  30 +
 pom.xml                                            | 177 +++++
 .../sling/formauth/AuthenticationFormServlet.java  | 127 ++++
 .../sling/formauth/FormAuthenticationHandler.java  | 751 +++++++++++++++++++++
 .../sling/formauth/FormLoginModulePlugin.java      | 106 +++
 .../java/org/apache/sling/formauth/TokenStore.java | 380 +++++++++++
 .../OSGI-INF/metatype/metatype.properties          |  68 ++
 src/main/resources/login.html                      |  65 ++
 .../formauth/FormAuthenticationHandlerTest.java    | 146 ++++
 9 files changed, 1850 insertions(+)

diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..322c689
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,30 @@
+Apache Sling Form Based Cookie Authenticator
+
+Bundle implementing form based authentication with login and logout support.
+Authentication state is maintained in a Cookie or in an HTTP Session. The
+password is only submitted when first authenticating.
+
+Getting Started
+===============
+
+This component uses a Maven 2 (http://maven.apache.org/) build
+environment. It requires a Java 5 JDK (or higher) and Maven
+(http://maven.apache.org/) 2.2.1 or later. We recommend to use the latest
+Maven version.
+
+If you have Maven 2 installed, you can compile and
+package the jar using the following command:
+
+    mvn package
+
+See the Maven 2 documentation for other build features.
+
+The latest source code for this component is available in the
+Subversion (http://subversion.tigris.org/) source repository of
+the Apache Software Foundation. If you have Subversion installed,
+you can checkout the latest source using the following command:
+
+    svn checkout http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth
+
+See the Subversion documentation for other source control features.
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..5732e73
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,177 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+    <!--
+        Licensed to the Apache Software Foundation (ASF) under one or
+        more contributor license agreements. See the NOTICE file
+        distributed with this work for additional information regarding
+        copyright ownership. The ASF licenses this file to you under the
+        Apache License, Version 2.0 (the "License"); you may not use
+        this file except in compliance with the License. You may obtain
+        a copy of the License at
+
+        http://www.apache.org/licenses/LICENSE-2.0 Unless required by
+        applicable law or agreed to in writing, software distributed
+        under the License is distributed on an "AS IS" BASIS, WITHOUT
+        WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+        See the License for the specific language governing permissions
+        and limitations under the License.
+    -->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>8</version>
+        <relativePath>../../../parent/pom.xml</relativePath>
+    </parent>
+
+    <artifactId>org.apache.sling.formauth</artifactId>
+    <version>0.9-SNAPSHOT</version>
+    <packaging>bundle</packaging>
+
+    <name>Apache Sling Form Based Authentication Handler</name>
+    <description>
+        Bundle implementing form based authentication with login
+        and logout support. Authentication state is maintained in
+        a Cookie or in an HTTP Session. The password is only submitted
+        when first authenticating.
+    </description>
+
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth</connection>
+        <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth</developerConnection>
+        <url>http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth</url>
+    </scm>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-scr-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.felix</groupId>
+                <artifactId>maven-bundle-plugin</artifactId>
+                <extensions>true</extensions>
+                <configuration>
+                    <instructions>
+                        <Bundle-DocURL>
+                            http://sling.apache.org/site/form-based-authenticationhandler.html
+                        </Bundle-DocURL>
+                        <Private-Package>
+                            org.apache.sling.formauth.*
+                        </Private-Package>
+                        <Import-Package>
+                            javax.security.auth.callback;
+                            javax.security.auth.login;
+                            org.apache.sling.jcr.jackrabbit.server.security;
+                            resolution:=optional,
+                            *
+                        </Import-Package>
+                        <Embed-Dependency>
+                            org.apache.sling.commons.osgi;inline="org/apache/sling/commons/osgi/OsgiUtil.*",
+                            commons-lang;inline="org/apache/commons/lang/StringUtils.class",
+                            commons-codec;inline="org/apache/commons/codec/binary/Base64.*
+                            |org/apache/commons/codec/binary/Hex*
+                            |org/apache/commons/codec/binary/StringUtils*
+                            |org/apache/commons/codec/BinaryEncoder*
+                            |org/apache/commons/codec/BinaryDecoder*
+                            |org/apache/commons/codec/Encoder*
+                            |org/apache/commons/codec/Decoder*
+                            |org/apache/commons/codec/EncoderException*
+                            |org/apache/commons/codec/DecoderException*"
+                        </Embed-Dependency>
+                    </instructions>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+    <reporting>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-javadoc-plugin</artifactId>
+                <configuration>
+                    <excludePackageNames>
+                        org.apache.sling.formauth
+                    </excludePackageNames>
+                </configuration>
+            </plugin>
+        </plugins>
+    </reporting>
+    <dependencies>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.api</artifactId>
+            <version>2.0.8</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.osgi</artifactId>
+            <version>2.0.4-incubator</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.engine</artifactId>
+            <version>2.0.6</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.commons.auth</artifactId>
+            <version>0.9.0-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>commons-codec</groupId>
+            <artifactId>commons-codec</artifactId>
+            <version>1.4</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>commons-lang</groupId>
+            <artifactId>commons-lang</artifactId>
+            <version>2.4</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.apache.sling</groupId>
+            <artifactId>org.apache.sling.jcr.jackrabbit.server</artifactId>
+            <version>2.0.5-SNAPSHOT</version>
+            <scope>provided</scope>
+        </dependency>
+
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.compendium</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jmock</groupId>
+            <artifactId>jmock-junit4</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-simple</artifactId>
+        </dependency>
+    </dependencies>
+</project>
diff --git a/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
new file mode 100644
index 0000000..7c9f789
--- /dev/null
+++ b/src/main/java/org/apache/sling/formauth/AuthenticationFormServlet.java
@@ -0,0 +1,127 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.formauth;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.commons.auth.Authenticator;
+
+/**
+ * The <code>AuthenticationFormServlet</code> provides the default login form
+ * used for Form Based Authentication.
+ *
+ * @scr.component metatype="no"
+ * @scr.service interface="javax.servlet.Servlet"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property name="service.description"
+ *               value="Default Login Form for Form Based Authentication"
+ */
+@SuppressWarnings("serial")
+public class AuthenticationFormServlet extends HttpServlet {
+
+    /**
+     * @scr.property name="sling.servlet.paths"
+     */
+    static final String SERVLET_PATH = "/system/sling/form/login";
+
+    /**
+     * @scr.property name="sling.auth.requirements"
+     */
+    @SuppressWarnings("unused")
+    private static final String AUTH_REQUIREMENT = "-" + SERVLET_PATH;
+
+    private volatile String rawForm;
+
+    @Override
+    protected void doGet(HttpServletRequest request,
+            HttpServletResponse response) throws IOException {
+
+        // setup the response for HTML and cache prevention
+        response.setContentType("text/html");
+        response.setCharacterEncoding("UTF-8");
+        response.setHeader("Cache-control", "no-cache");
+        response.addHeader("Cache-control", "no-store");
+        response.setHeader("Pragma", "no-cache");
+        response.setHeader("Expires", "0");
+
+        // send the form and flush
+        response.getWriter().print(getForm(request));
+        response.flushBuffer();
+    }
+
+    @Override
+    protected void doPost(HttpServletRequest request,
+            HttpServletResponse response) throws ServletException, IOException {
+        super.doPost(request, response);
+    }
+
+    private String getForm(final HttpServletRequest request) throws IOException {
+
+        String resource = (String) request.getAttribute(Authenticator.LOGIN_RESOURCE);
+        if (resource == null) {
+            resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
+            if (resource == null) {
+                resource = "/";
+            }
+        }
+
+        return getRawForm().replace("${resource}", resource);
+    }
+
+    private String getRawForm() throws IOException {
+        if (rawForm == null) {
+            InputStream ins = null;
+            try {
+                ins = getClass().getResourceAsStream("/login.html");
+                if (ins != null) {
+                    StringBuilder builder = new StringBuilder();
+                    Reader r = new InputStreamReader(ins, "UTF-8");
+                    char[] cbuf = new char[1024];
+                    int rd = 0;
+                    while ((rd = r.read(cbuf)) >= 0) {
+                        builder.append(cbuf, 0, rd);
+                    }
+
+                    rawForm = builder.toString();
+                }
+            } finally {
+                if (ins != null) {
+                    try {
+                        ins.close();
+                    } catch (IOException ignore) {
+                    }
+                }
+            }
+
+            if (rawForm == null) {
+                throw new IOException("Failed reading form template");
+            }
+        }
+
+        return rawForm;
+    }
+}
diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
new file mode 100644
index 0000000..c135cc4
--- /dev/null
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -0,0 +1,751 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.formauth;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.URLEncoder;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Dictionary;
+
+import javax.jcr.Credentials;
+import javax.jcr.SimpleCredentials;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.StringUtils;
+import org.apache.sling.commons.auth.Authenticator;
+import org.apache.sling.commons.auth.spi.AuthenticationFeedbackHandler;
+import org.apache.sling.commons.auth.spi.AuthenticationHandler;
+import org.apache.sling.commons.auth.spi.AuthenticationInfo;
+import org.apache.sling.commons.auth.spi.DefaultAuthenticationFeedbackHandler;
+import org.apache.sling.commons.osgi.OsgiUtil;
+import org.osgi.framework.BundleContext;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>CookieAuthenticationHandler</code> class implements the
+ * authorization steps based on a cookie.
+ *
+ * @scr.component immediate="false" label="%auth.form.name"
+ *                description="%auth.form.description"
+ * @scr.property name="service.description"
+ *               value="Cookie Based Authentication Handler"
+ * @scr.property name="service.vendor" value="The Apache Software Foundation"
+ * @scr.property nameRef="AuthenticationHandler.PATH_PROPERTY" value="/"
+ * @scr.service
+ */
+public class FormAuthenticationHandler implements AuthenticationHandler,
+        AuthenticationFeedbackHandler {
+
+    /**
+     * The request parameter causing a 401/UNAUTHORIZED status to be sent back
+     * in the {@link #authenticate(HttpServletRequest, HttpServletResponse)}
+     * method if no credentials are present in the request (value is
+     * "sling:authRequestLogin").
+     *
+     * @see #requestCredentials(HttpServletRequest, HttpServletResponse)
+     */
+    static final String REQUEST_LOGIN_PARAMETER = "sling:authRequestLogin";
+
+    /**
+     * The name of the parameter providing the login form URL.
+     *
+     * @scr.property valueRef="AuthenticationFormServlet.SERVLET_PATH"
+     */
+    private static final String PAR_LOGIN_FORM = "form.login.form";
+
+    /**
+     * @scr.property valueRef="DEFAULT_AUTH_STORAGE" options "cookie"="Cookie"
+     *               "session"="Session Attribute"
+     */
+    private static final String PAR_AUTH_STORAGE = "form.auth.storage";
+
+    /**
+     * The value of the {@link #PAR_AUTH_STORAGE} parameter indicating the use
+     * of a Cookie to store the authentication data.
+     */
+    private static final String AUTH_STORAGE_COOKIE = "cookie";
+
+    /**
+     * The value of the {@link #PAR_AUTH_STORAGE} parameter indicating the use
+     * of a session attribute to store the authentication data.
+     */
+    private static final String AUTH_STORAGE_SESSION_ATTRIBUTE = "session";
+
+    /**
+     * To be used to determine if the auth has value comes from a cookie or from
+     * a session attribute.
+     */
+    private static final String DEFAULT_AUTH_STORAGE = AUTH_STORAGE_COOKIE;
+
+    /**
+     * The name of the configuration parameter providing the Cookie or session
+     * attribute name.
+     *
+     * @scr.property valueRef="DEFAULT_AUTH_NAME"
+     */
+    private static final String PAR_AUTH_NAME = "form.auth.name";
+
+    /**
+     * The default Cookie or session attribute name
+     *
+     * @see #PAR_AUTH_NAME
+     */
+    private static final String DEFAULT_AUTH_NAME = "sling.formauth";
+
+    /**
+     * This is the name of the SimpleCredentials attribute that holds the auth
+     * info extracted from the cookie value.
+     *
+     * @scr.property valueRef="DEFAULT_CREDENTIALS_ATTRIBUTE_NAME"
+     */
+    private static final String PAR_CREDENTIALS_ATTRIBUTE_NAME = "form.credentials.name";
+
+    /**
+     * Default value for the {@link #PAR_CREDENTIALS_ATTRIBUTE_NAME} property
+     */
+    private static final String DEFAULT_CREDENTIALS_ATTRIBUTE_NAME = DEFAULT_AUTH_NAME;
+
+    /**
+     * The number of minutes after which a login session times out. This value
+     * is used as the expiry time set in the authentication data.
+     *
+     * @scr.property type="Integer" valueRef="DEFAULT_AUTH_TIMEOUT"
+     */
+    public static final String PAR_AUTH_TIMEOUT = "form.auth.timeout";
+
+    /**
+     * The default authentication data time out value.
+     *
+     * @see #PAR_AUTH_TIMEOUT
+     */
+    private static final int DEFAULT_AUTH_TIMEOUT = 30;
+
+    /**
+     * The name of the file used to persist the security tokens
+     *
+     * @scr.property valueRef="DEFAULT_TOKEN_FILE"
+     */
+    private static final String PAR_TOKEN_FILE = "form.token.file";
+
+    private static final String DEFAULT_TOKEN_FILE = "cookie-tokens.bin";
+
+    /**
+     * The request method required for user name and password submission by the
+     * form (value is "POST").
+     */
+    private static final String REQUEST_METHOD = "POST";
+
+    /**
+     * The last segment of the request URL for the user name and password
+     * submission by the form (value is "/j_security_check").
+     * <p>
+     * This name is derived from the prescription in the Servlet API 2.4
+     * Specification, Section SRV.12.5.3.1 Login Form Notes: <i>In order for the
+     * authentication to proceeed appropriately, the action of the login form
+     * must always be set to <code>j_security_check</code>.</i>
+     */
+    private static final String REQUEST_URL_SUFFIX = "/j_security_check";
+
+    /**
+     * The name of the form submission parameter providing the name of the user
+     * to authenticate (value is "j_username").
+     * <p>
+     * This name is prescribed by the Servlet API 2.4 Specification, Section
+     * SRV.12.5.3 Form Based Authentication.
+     */
+    private static final String PAR_J_USERNAME = "j_username";
+
+    /**
+     * The name of the form submission parameter providing the password of the
+     * user to authenticate (value is "j_password").
+     * <p>
+     * This name is prescribed by the Servlet API 2.4 Specification, Section
+     * SRV.12.5.3 Form Based Authentication.
+     */
+    private static final String PAR_J_PASSWORD = "j_password";
+
+    /**
+     * The factor to convert minute numbers into milliseconds used internally
+     */
+    private static final long MINUTES = 60L * 1000L;
+
+
+    /** default log */
+    private final Logger log = LoggerFactory.getLogger(getClass());
+
+    private AuthenticationStorage authStorage;
+
+    private String loginForm;
+
+    /**
+     * The timeout of a login session in milliseconds, converted from the
+     * configuration property {@link #PAR_AUTH_TIMEOUT} by multiplying with
+     * {@link #MINUTES}.
+     */
+    private long sessionTimeout;
+
+    private String attrCookieAuthData;
+
+    private TokenStore tokenStore;
+
+    /**
+     * 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
+     * the secure user data is not present either in the cookie or an HTTP
+     * Session.
+     */
+    public AuthenticationInfo extractCredentials(HttpServletRequest request,
+            HttpServletResponse response) {
+
+        AuthenticationInfo info = null;
+
+        // 1. try credentials from POST'ed request parameters
+        info = this.extractRequestParameterAuthentication(request);
+
+        // 2. try credentials from the cookie or session
+        if (info == null) {
+            String authData = authStorage.extractAuthenticationInfo(request);
+            if (authData != null && tokenStore.isValid(authData)) {
+                info = createAuthInfo(authData);
+            }
+        }
+
+        return info;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.sling.commons.auth.spi.AuthenticationHandler#requestCredentials
+     * (javax.servlet.http.HttpServletRequest,
+     * javax.servlet.http.HttpServletResponse)
+     */
+    public boolean requestCredentials(HttpServletRequest request,
+            HttpServletResponse response) throws IOException {
+
+        // 0. ignore this handler if an authentication handler is requested
+        if (ignoreRequestCredentials(request)) {
+            return false;
+        }
+
+        String resource = (String) request.getAttribute(Authenticator.LOGIN_RESOURCE);
+        if (resource == null || resource.length() == 0) {
+            resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
+            if (resource == null || resource.length() == 0) {
+                resource = request.getRequestURI();
+            }
+        }
+
+        final StringBuilder targetBuilder = new StringBuilder();
+        targetBuilder.append(request.getContextPath());
+        targetBuilder.append(loginForm);
+        targetBuilder.append('?').append(Authenticator.LOGIN_RESOURCE);
+        targetBuilder.append("=").append(URLEncoder.encode(resource, "UTF-8"));
+
+        final String target = targetBuilder.toString();
+        try {
+            response.sendRedirect(target);
+        } catch (IOException e) {
+            log.error("Failed to redirect to the page: " + target, e);
+        }
+
+        return true;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see
+     * org.apache.sling.commons.auth.spi.AuthenticationHandler#dropCredentials
+     * (javax.servlet.http.HttpServletRequest,
+     * javax.servlet.http.HttpServletResponse)
+     */
+    public void dropCredentials(HttpServletRequest request,
+            HttpServletResponse response) {
+
+        authStorage.clear(request, response);
+
+        // if there is a referer header, redirect back there
+        // with an anonymous session
+        String referer = request.getHeader("referer");
+        if (referer == null) {
+            referer = request.getContextPath() + "/";
+        }
+
+        try {
+            response.sendRedirect(referer);
+        } catch (IOException e) {
+            log.error("Failed to redirect to the page: " + referer, e);
+        }
+    }
+
+    // ---------- AuthenticationFeedbackHandler
+
+    /**
+     * Called after an unsuccessful login attempt. This implementation makes
+     * sure the authentication data is removed either by removing the cookie or
+     * by remove the HTTP Session attribute.
+     */
+    public void authenticationFailed(HttpServletRequest request,
+            HttpServletResponse response, AuthenticationInfo authInfo) {
+        authStorage.clear(request, response);
+    }
+
+    /**
+     * Called after successfull login with the given authentication info. This
+     * implementation ensures the authentication data is set in either the
+     * cookie or the HTTP session with the correct security tokens.
+     * <p>
+     * If no authentication data already exists, it is created. Otherwise if the
+     * data has expired the data is updated with a new security token and a new
+     * expiry time.
+     * <p>
+     * If creating or updating the authentication data fails, it is actually
+     * removed from the cookie or the HTTP session and future requests will not
+     * be authenticated any longer.
+     */
+    public boolean authenticationSucceeded(HttpServletRequest request,
+            HttpServletResponse response, AuthenticationInfo authInfo) {
+
+        // get current authentication data, may be missing after first login
+        String authData = getCookieAuthData(authInfo.getCredentials());
+
+        // check whether we have to "store" or create the data
+        final boolean refreshCookie = needsRefresh(authData,
+            this.sessionTimeout);
+
+        // add or refresh the stored auth hash
+        if (refreshCookie) {
+            long expires = System.currentTimeMillis() + this.sessionTimeout;
+            try {
+                authData = null;
+                authData = tokenStore.encode(expires, authInfo.getUser());
+            } catch (InvalidKeyException e) {
+                log.error(e.getMessage(), e);
+            } catch (IllegalStateException e) {
+                log.error(e.getMessage(), e);
+            } catch (UnsupportedEncodingException e) {
+                log.error(e.getMessage(), e);
+            } catch (NoSuchAlgorithmException e) {
+                log.error(e.getMessage(), e);
+            }
+
+            if (authData != null) {
+                authStorage.set(request, response, authData);
+            } else {
+                authStorage.clear(request, response);
+            }
+        }
+
+        if (!DefaultAuthenticationFeedbackHandler.handleRedirect(request,
+            response)) {
+
+            String resource = (String) request.getAttribute(Authenticator.LOGIN_RESOURCE);
+            if (resource == null || resource.length() == 0) {
+                resource = request.getParameter(Authenticator.LOGIN_RESOURCE);
+            }
+            if (resource != null && resource.length() > 0) {
+                try {
+                    response.sendRedirect(resource);
+                } catch (IOException ioe) {
+                }
+                return true;
+            }
+
+        }
+
+        // no redirect
+        return false;
+    }
+
+    @Override
+    public String toString() {
+        return "Form Based Authentication Handler";
+    }
+
+    // --------- Force HTTP Basic Auth ---------
+
+    /**
+     * Returns <code>true</code> if this authentication handler should ignore
+     * the call to
+     * {@link #requestCredentials(HttpServletRequest, HttpServletResponse)}.
+     * <p>
+     * This method returns <code>true</code> if the
+     * {@link #REQUEST_LOGIN_PARAMETER} is set to any value other than "Form"
+     * (HttpServletRequest.FORM_AUTH).
+     */
+    private boolean ignoreRequestCredentials(HttpServletRequest request) {
+        final String requestLogin = request.getParameter(REQUEST_LOGIN_PARAMETER);
+        return requestLogin != null
+            && !HttpServletRequest.FORM_AUTH.equals(requestLogin);
+    }
+
+    // --------- Request Parameter Auth ---------
+
+    private AuthenticationInfo extractRequestParameterAuthentication(
+            HttpServletRequest request) {
+        AuthenticationInfo info = null;
+
+        // only consider login form parameters if this is a POST request
+        // to the j_security_check URL
+        if (REQUEST_METHOD.equals(request.getMethod())
+            && request.getRequestURI().endsWith(REQUEST_URL_SUFFIX)) {
+
+            String user = request.getParameter(PAR_J_USERNAME);
+            String pwd = request.getParameter(PAR_J_PASSWORD);
+
+            if (user != null && user.length() > 0 && pwd != null) {
+                info = new AuthenticationInfo(HttpServletRequest.FORM_AUTH,
+                    user, pwd.toCharArray());
+            }
+        }
+
+        return info;
+    }
+
+    private AuthenticationInfo createAuthInfo(final String authData) {
+        final String userId = getUserId(authData);
+        if (userId == null) {
+            return null;
+        }
+
+        final SimpleCredentials cookieAuthCredentials = new SimpleCredentials(
+            userId, new char[0]);
+        cookieAuthCredentials.setAttribute(attrCookieAuthData, authData);
+
+        final AuthenticationInfo info = new AuthenticationInfo(
+            HttpServletRequest.FORM_AUTH, userId);
+        info.setCredentials(cookieAuthCredentials);
+
+        return info;
+    }
+
+    // ---------- LoginModulePlugin support
+
+    private String getCookieAuthData(final Credentials credentials) {
+        if (credentials instanceof SimpleCredentials) {
+            Object data = ((SimpleCredentials) credentials).getAttribute(attrCookieAuthData);
+            if (data instanceof String) {
+                return (String) data;
+            }
+        }
+
+        // no SimpleCredentials or no valid attribute
+        return null;
+    }
+
+    boolean hasAuthData(final Credentials credentials) {
+        return getCookieAuthData(credentials) != null;
+    }
+
+    boolean isValid(final Credentials credentials) {
+        String authData = getCookieAuthData(credentials);
+        if (authData != null) {
+            return tokenStore.isValid(authData);
+        }
+
+        // no authdata, not valid
+        return false;
+    }
+
+    // ---------- SCR Integration ----------------------------------------------
+
+    /**
+     * Called by SCR to activate the authentication handler.
+     *
+     * @throws InvalidKeyException
+     * @throws NoSuchAlgorithmException
+     * @throws IllegalStateException
+     * @throws UnsupportedEncodingException
+     */
+    protected void activate(ComponentContext componentContext)
+            throws InvalidKeyException, NoSuchAlgorithmException,
+            IllegalStateException, UnsupportedEncodingException {
+
+        Dictionary<?, ?> properties = componentContext.getProperties();
+
+        this.loginForm = OsgiUtil.toString(properties.get(PAR_LOGIN_FORM),
+            AuthenticationFormServlet.SERVLET_PATH);
+        log.info("Login Form URL {}", loginForm);
+
+        final String authName = OsgiUtil.toString(
+            properties.get(PAR_AUTH_NAME), DEFAULT_AUTH_NAME);
+        final String authStorage = OsgiUtil.toString(
+            properties.get(PAR_AUTH_STORAGE), DEFAULT_AUTH_STORAGE);
+        if (AUTH_STORAGE_SESSION_ATTRIBUTE.equals(authStorage)) {
+
+            this.authStorage = new SessionStorage(authName);
+            log.info("Using HTTP Session store with attribute name {}",
+                authName);
+
+        } else {
+
+            this.authStorage = new CookieStorage(authName);
+            log.info("Using Cookie store with name {}", authName);
+
+        }
+
+        this.attrCookieAuthData = OsgiUtil.toString(
+            properties.get(PAR_CREDENTIALS_ATTRIBUTE_NAME),
+            DEFAULT_CREDENTIALS_ATTRIBUTE_NAME);
+        log.info("Setting Auth Data attribute name {}", attrCookieAuthData);
+
+        int timeoutMinutes = OsgiUtil.toInteger(
+            properties.get(PAR_AUTH_TIMEOUT), DEFAULT_AUTH_TIMEOUT);
+        if (timeoutMinutes < 1) {
+            timeoutMinutes = DEFAULT_AUTH_TIMEOUT;
+        }
+        log.info("Setting session timeout {} minutes", timeoutMinutes);
+        this.sessionTimeout = MINUTES * timeoutMinutes;
+
+        final String tokenFileName = OsgiUtil.toString(
+            properties.get(PAR_TOKEN_FILE), DEFAULT_TOKEN_FILE);
+        final File tokenFile = getTokenFile(tokenFileName,
+            componentContext.getBundleContext());
+        log.info("Storing tokens in ", tokenFile);
+        this.tokenStore = new TokenStore(tokenFile, sessionTimeout);
+    }
+
+    /**
+     * Returns an absolute file indicating the file to use to persist the
+     * security tokens.
+     * <p>
+     * This method is not part of the API of this class and is package private
+     * to enable unit tests.
+     *
+     * @param tokenFileName The configured file name, must not be null
+     * @param bundleContext The BundleContext to use to make an relative file
+     *            absolute
+     * @return The absolute file
+     */
+    File getTokenFile(final String tokenFileName,
+            final BundleContext bundleContext) {
+        File tokenFile = new File(tokenFileName);
+        if (tokenFile.isAbsolute()) {
+            return tokenFile;
+        }
+
+        tokenFile = bundleContext.getDataFile(tokenFileName);
+        if (tokenFile == null) {
+            final String slingHome = bundleContext.getProperty("sling.home");
+            if (slingHome != null) {
+                tokenFile = new File(slingHome, tokenFileName);
+            } else {
+                tokenFile = new File(tokenFileName);
+            }
+        }
+
+        return tokenFile.getAbsoluteFile();
+    }
+
+    /**
+     * Returns the user id from the authentication data. If the authentication
+     * data is a non-<code>null</code> value with 3 fields separated by an @
+     * sign, the value of the third field is returned. Otherwise
+     * <code>null</code> is returned.
+     * <p>
+     * This method is not part of the API of this class and is package private
+     * to enable unit tests.
+     *
+     * @param authData
+     * @return
+     */
+    String getUserId(final String authData) {
+        if (authData != null) {
+            String[] parts = StringUtils.split(authData, "@");
+            if (parts != null && parts.length == 3) {
+                return parts[2];
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Refresh the cookie periodically.
+     *
+     * @param sessionTimeout time to live for the session
+     * @return true or false
+     */
+    private boolean needsRefresh(final String authData,
+            final long sessionTimeout) {
+        boolean updateCookie = false;
+        if (authData == null) {
+            updateCookie = true;
+        } else {
+            String[] parts = StringUtils.split(authData, "@");
+            if (parts != null && parts.length == 3) {
+                long cookieTime = Long.parseLong(parts[1].substring(1));
+                if (System.currentTimeMillis() + (sessionTimeout / 2) > cookieTime) {
+                    updateCookie = true;
+                }
+            }
+        }
+        return updateCookie;
+    }
+
+    /**
+     * The <code>AuthenticationStorage</code> interface abstracts the API
+     * required to store the {@link CookieAuthData} in an HTTP cookie or in an
+     * HTTP Session. The concrete class -- {@link CookieExtractor} or
+     * {@link SessionExtractor} -- is selected using the
+     * {@link CookieAuthenticationHandler#PAR_AUTH_HASH_STORAGE} configuration
+     * parameter, {@link CookieExtractor} by default.
+     */
+    private static interface AuthenticationStorage {
+        String extractAuthenticationInfo(HttpServletRequest request);
+
+        void set(HttpServletRequest request, HttpServletResponse response,
+                String authData);
+
+        void clear(HttpServletRequest request, HttpServletResponse response);
+    }
+
+    /**
+     * The <code>CookieExtractor</code> class supports storing the
+     * {@link CookieAuthData} in an HTTP Cookie.
+     */
+    private static class CookieStorage implements AuthenticationStorage {
+        private final String cookieName;
+
+        public CookieStorage(final String cookieName) {
+            this.cookieName = cookieName;
+        }
+
+        public String extractAuthenticationInfo(HttpServletRequest request) {
+            Cookie[] cookies = request.getCookies();
+            if (cookies != null) {
+                for (Cookie cookie : cookies) {
+                    if (this.cookieName.equals(cookie.getName())) {
+                        // found the cookie, so try to extract the credentials
+                        // from it
+                        String value = cookie.getValue();
+
+                        // reverse the base64 encoding
+                        try {
+                            return new String(Base64.decodeBase64(value),
+                                "UTF-8");
+                        } catch (UnsupportedEncodingException e1) {
+                            throw new RuntimeException(e1);
+                        }
+                    }
+                }
+            }
+
+            return null;
+        }
+
+        public void set(HttpServletRequest request,
+                HttpServletResponse response, String authData) {
+            // base64 encode to handle any special characters
+            String cookieValue;
+            try {
+                cookieValue = Base64.encodeBase64URLSafeString(authData.getBytes("UTF-8"));
+            } catch (UnsupportedEncodingException e1) {
+                throw new RuntimeException(e1);
+            }
+
+            // send the cookie to the response
+            setCookie(request, response, cookieValue, -1);
+        }
+
+        public void clear(HttpServletRequest request,
+                HttpServletResponse response) {
+            Cookie oldCookie = null;
+            Cookie[] cookies = request.getCookies();
+            if (cookies != null) {
+                for (Cookie cookie : cookies) {
+                    if (this.cookieName.equals(cookie.getName())) {
+                        // found the cookie
+                        oldCookie = cookie;
+                        break;
+                    }
+                }
+            }
+
+            // remove the old cookie from the client
+            if (oldCookie != null) {
+                setCookie(request, response, "", 0);
+            }
+        }
+
+        private void setCookie(final HttpServletRequest request,
+                final HttpServletResponse response, final String value,
+                final int age) {
+
+            final String ctxPath = request.getContextPath();
+            final String cookiePath = (ctxPath == null || ctxPath.length() == 0)
+                    ? "/"
+                    : ctxPath;
+
+            Cookie cookie = new Cookie(this.cookieName, value);
+            cookie.setMaxAge(age);
+            cookie.setPath(cookiePath);
+            cookie.setSecure(request.isSecure());
+            response.addCookie(cookie);
+        }
+    }
+
+    /**
+     * The <code>SessionExtractor</code> class provides support to store the
+     * {@link CookieAuthData} in an HTTP Session.
+     */
+    private static class SessionStorage implements AuthenticationStorage {
+        private final String sessionAttributeName;
+
+        SessionStorage(final String sessionAttributeName) {
+            this.sessionAttributeName = sessionAttributeName;
+        }
+
+        public String extractAuthenticationInfo(HttpServletRequest request) {
+            HttpSession session = request.getSession(false);
+            if (session != null) {
+                Object attribute = session.getAttribute(sessionAttributeName);
+                if (attribute instanceof String) {
+                    return (String) attribute;
+                }
+            }
+            return null;
+        }
+
+        public void set(HttpServletRequest request,
+                HttpServletResponse response, String authData) {
+            // store the auth hash as a session attribute
+            HttpSession session = request.getSession();
+            session.setAttribute(sessionAttributeName, authData);
+        }
+
+        public void clear(HttpServletRequest request,
+                HttpServletResponse response) {
+            HttpSession session = request.getSession(false);
+            if (session != null) {
+                session.removeAttribute(sessionAttributeName);
+            }
+        }
+
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
new file mode 100644
index 0000000..e4b60dd
--- /dev/null
+++ b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.formauth;
+
+import java.security.Principal;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.Credentials;
+import javax.jcr.Session;
+import javax.jcr.SimpleCredentials;
+import javax.security.auth.callback.CallbackHandler;
+import org.apache.sling.jcr.jackrabbit.server.security.AuthenticationPlugin;
+import org.apache.sling.jcr.jackrabbit.server.security.LoginModulePlugin;
+
+final class FormLoginModulePlugin implements LoginModulePlugin {
+
+    private final FormAuthenticationHandler authHandler;
+
+    FormLoginModulePlugin(final FormAuthenticationHandler authHandler) {
+        this.authHandler = authHandler;
+    }
+
+    /**
+     * Returns <code>true</code> indicating support if the credentials is a
+     * <code>SimplerCredentials</code> object and has an authentication data
+     * attribute.
+     *
+     * @see CookieAuthenticationHandler#hasAuthData(Credentials)
+     */
+    public boolean canHandle(Credentials credentials) {
+        return authHandler.hasAuthData(credentials);
+    }
+
+    /**
+     * This implementation does nothing.
+     */
+    @SuppressWarnings("unchecked")
+    public void doInit(CallbackHandler callbackHandler, Session session,
+            Map options) {
+    }
+
+    /**
+     * Returns a simple <code>Principal</code> just providing the user id
+     * contained in the <code>SimpleCredentials</code> object. If the
+     * credentials is not a <code>SimpleCredentials</code> instance,
+     * <code>null</code> is returned.
+     */
+    public Principal getPrincipal(final Credentials credentials) {
+        if (credentials instanceof SimpleCredentials) {
+            return new Principal() {
+                public String getName() {
+                    return ((SimpleCredentials) credentials).getUserID();
+                }
+            };
+        }
+        return null;
+    }
+
+    /**
+     * This implementation does nothing.
+     */
+    @SuppressWarnings("unchecked")
+    public void addPrincipals(Set principals) {
+    }
+
+    /**
+     * Returns an <code>AuthenticationPlugin</code> which authenticates the
+     * credentials if the contain authentication data and the authentication
+     * data can is valid.
+     *
+     * @see CookieAuthenticationHandler#isValid(Credentials)
+     */
+    public AuthenticationPlugin getAuthentication(Principal principal,
+            Credentials creds) {
+        return new AuthenticationPlugin() {
+            public boolean authenticate(Credentials credentials) {
+                return authHandler.isValid(credentials);
+            }
+        };
+    }
+
+    /**
+     * Returns <code>LoginModulePlugin.IMPERSONATION_DEFAULT</code> to indicate
+     * that this plugin does not itself handle impersonation requests.
+     */
+    public int impersonate(Principal principal, Credentials credentials) {
+        return LoginModulePlugin.IMPERSONATION_DEFAULT;
+    }
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/formauth/TokenStore.java b/src/main/java/org/apache/sling/formauth/TokenStore.java
new file mode 100644
index 0000000..390f1b2
--- /dev/null
+++ b/src/main/java/org/apache/sling/formauth/TokenStore.java
@@ -0,0 +1,380 @@
+/*
+ * Licensed to the Sakai Foundation (SF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The SF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations under the License.
+ */
+package org.apache.sling.formauth;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+
+import javax.crypto.Mac;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.lang.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * The <code>TokenStore</code> class provides the secure token hash
+ * implementation used by the {@link FormAuthenticationHandler} to generate,
+ * validate and persist secure tokens.
+ */
+class TokenStore {
+
+    /**
+     * Array of hex characters used by {@link #byteToHex(byte[])} to convert a
+     * byte array to a hex string.
+     */
+    private static final char[] TOHEX = "0123456789abcdef".toCharArray();
+
+    /**
+     * Name of the <code>SecureRandom</code> generator algorithm
+     */
+    private static final String SHA1PRNG = "SHA1PRNG";
+
+    /**
+     * The name of the HMAC function to calculate the hash code of the payload
+     * with the secure token.
+     */
+    private static final String HMAC_SHA1 = "HmacSHA1";
+
+    /**
+     * String encoding to convert byte arrays to strings and vice-versa.
+     */
+    private static final String UTF_8 = "UTF-8";
+
+    /** The number of secret keys in the token buffer currentTokens */
+    private static final int TOKEN_BUFFER_SIZE = 5;
+
+    public final Logger log = LoggerFactory.getLogger(TokenStore.class);
+
+    /**
+     * The ttl of the cookie before it becomes invalid (in ms)
+     */
+    private final long ttl;
+
+    /**
+     * The time when a new token should be created.
+     */
+    private long nextUpdate = System.currentTimeMillis();
+
+    /**
+     * The location of the current token.
+     */
+    private volatile int currentToken = 0;
+
+    /**
+     * A ring of tokens used to encypt.
+     */
+    private volatile SecretKey[] currentTokens;
+
+    /**
+     * A secure random used for generating new tokens.
+     */
+    private SecureRandom random;
+
+    /** The token file to persist the secure tokens */
+    private File tokenFile;
+
+    /** A temporary file used to update the secure token file */
+    private File tmpTokenFile;
+
+    /**
+     * @throws NoSuchAlgorithmException
+     * @throws InvalidKeyException
+     * @throws UnsupportedEncodingException
+     * @throws IllegalStateException
+     * @throws NullPointerException if <code>tokenFile</code> is
+     *             <code>null</code>.
+     */
+    TokenStore(final File tokenFile, final long sessionTimeout)
+            throws NoSuchAlgorithmException, InvalidKeyException,
+            IllegalStateException, UnsupportedEncodingException {
+
+        if (tokenFile == null) {
+            throw new NullPointerException("tokenfile");
+        }
+
+        this.random = SecureRandom.getInstance(SHA1PRNG);
+        this.ttl = sessionTimeout;
+        this.tokenFile = tokenFile;
+        this.tmpTokenFile = new File(tokenFile + ".tmp");
+
+        // prime the secret keys from persistence
+        loadTokens();
+
+        // warm up the crypto API
+        byte[] b = new byte[20];
+        random.nextBytes(b);
+        final SecretKey secretKey = new SecretKeySpec(b, HMAC_SHA1);
+        final Mac m = Mac.getInstance(HMAC_SHA1);
+        m.init(secretKey);
+        m.update(UTF_8.getBytes(UTF_8));
+        m.doFinal();
+    }
+
+    /**
+     * @param expires
+     * @param userId
+     * @return
+     * @throws UnsupportedEncodingException
+     * @throws IllegalStateException
+     * @throws NoSuchAlgorithmException
+     * @throws InvalidKeyException
+     */
+    String encode(final long expires, final String userId)
+            throws IllegalStateException, UnsupportedEncodingException,
+            NoSuchAlgorithmException, InvalidKeyException {
+        int token = getActiveToken();
+        SecretKey key = currentTokens[token];
+        return encode(expires, userId, token, key);
+    }
+
+    private String encode(final long expires, final String userId,
+            final int token, final SecretKey key) throws IllegalStateException,
+            UnsupportedEncodingException, NoSuchAlgorithmException,
+            InvalidKeyException {
+
+        String cookiePayload = String.valueOf(token) + String.valueOf(expires)
+            + "@" + userId;
+        Mac m = Mac.getInstance(HMAC_SHA1);
+        m.init(key);
+        m.update(cookiePayload.getBytes(UTF_8));
+        String cookieValue = byteToHex(m.doFinal());
+        return cookieValue + "@" + cookiePayload;
+    }
+
+    /**
+     * Returns <code>true</code> if the <code>value</code> is a valid secure
+     * token as follows:
+     * <ul>
+     * <li>The string is not <code>null</code></li>
+     * <li>The string contains three fields separated by an @ sign</li>
+     * <li>The expiry time encoded in the second field has not yet passed</li>
+     * <li>The hashing the third field, the expiry time and token number with
+     * the secure token (indicated by the token number) gives the same value as
+     * contained in the first field</li>
+     * </ul>
+     * <p>
+     * Otherwise the method returns <code>false</code>.
+     */
+    boolean isValid(String value) {
+        String[] parts = StringUtils.split(value, "@");
+        if (parts != null && parts.length == 3) {
+
+            // single digit token number
+            int tokenNumber = parts[1].charAt(0) - '0';
+            if (tokenNumber >= 0 && tokenNumber < currentTokens.length) {
+
+                long cookieTime = Long.parseLong(parts[1].substring(1));
+                if (System.currentTimeMillis() < cookieTime) {
+
+                    try {
+                        SecretKey secretKey = currentTokens[tokenNumber];
+                        String hmac = encode(cookieTime, parts[2], tokenNumber,
+                            secretKey);
+                        return value.equals(hmac);
+                    } catch (ArrayIndexOutOfBoundsException e) {
+                        log.error(e.getMessage(), e);
+                    } catch (InvalidKeyException e) {
+                        log.error(e.getMessage(), e);
+                    } catch (IllegalStateException e) {
+                        log.error(e.getMessage(), e);
+                    } catch (UnsupportedEncodingException e) {
+                        log.error(e.getMessage(), e);
+                    } catch (NoSuchAlgorithmException e) {
+                        log.error(e.getMessage(), e);
+                    }
+
+                    log.error("AuthNCookie value '{}' is invalid", value);
+
+                } else {
+                    log.error("AuthNCookie value '{}' has expired {}ms ago",
+                        value, (System.currentTimeMillis() - cookieTime));
+                }
+
+            } else {
+                log.error(
+                    "AuthNCookie value '{}' is invalid: refers to an invalid token number",
+                    value, tokenNumber);
+            }
+
+        } else {
+            log.error("AuthNCookie value '{}' has invalid format", value);
+        }
+
+        // failed verification, reason is logged
+        return false;
+    }
+
+    /**
+     * Maintain a circular buffer to tokens, and return the current one.
+     *
+     * @return the current token.
+     */
+    private synchronized int getActiveToken() {
+        if (System.currentTimeMillis() > nextUpdate
+            || currentTokens[currentToken] == null) {
+            // cycle so that during a typical ttl the tokens get completely
+            // refreshed.
+            nextUpdate = System.currentTimeMillis() + ttl
+                / (currentTokens.length - 1);
+            byte[] b = new byte[20];
+            random.nextBytes(b);
+
+            SecretKey newToken = new SecretKeySpec(b, HMAC_SHA1);
+            int nextToken = currentToken + 1;
+            if (nextToken == currentTokens.length) {
+                nextToken = 0;
+            }
+            currentTokens[nextToken] = newToken;
+            currentToken = nextToken;
+            saveTokens();
+        }
+        return currentToken;
+    }
+
+    /**
+     * Stores the current set of tokens to the token file
+     */
+    private void saveTokens() {
+        FileOutputStream fout = null;
+        DataOutputStream keyOutputStream = null;
+        try {
+            File parent = tokenFile.getAbsoluteFile().getParentFile();
+            log.info("Token File {} parent {} ", tokenFile, parent);
+            if (!parent.exists()) {
+                parent.mkdirs();
+            }
+            fout = new FileOutputStream(tmpTokenFile);
+            keyOutputStream = new DataOutputStream(fout);
+            keyOutputStream.writeInt(currentToken);
+            keyOutputStream.writeLong(nextUpdate);
+            for (int i = 0; i < currentTokens.length; i++) {
+                if (currentTokens[i] == null) {
+                    keyOutputStream.writeInt(0);
+                } else {
+                    keyOutputStream.writeInt(1);
+                    byte[] b = currentTokens[i].getEncoded();
+                    keyOutputStream.writeInt(b.length);
+                    keyOutputStream.write(b);
+                }
+            }
+            keyOutputStream.close();
+            tmpTokenFile.renameTo(tokenFile);
+        } catch (IOException e) {
+            log.error("Failed to save cookie keys " + e.getMessage());
+        } finally {
+            try {
+                keyOutputStream.close();
+            } catch (Exception e) {
+            }
+            try {
+                fout.close();
+            } catch (Exception e) {
+            }
+
+        }
+    }
+
+    /**
+     * Load the current set of tokens from the token file. If reading the tokens
+     * fails or the token file does not exist, tokens will be generated on
+     * demand.
+     */
+    private void loadTokens() {
+        if (tokenFile.isFile() && tokenFile.canRead()) {
+            FileInputStream fin = null;
+            DataInputStream keyInputStream = null;
+            try {
+                fin = new FileInputStream(tokenFile);
+                keyInputStream = new DataInputStream(fin);
+                int newCurrentToken = keyInputStream.readInt();
+                long newNextUpdate = keyInputStream.readLong();
+                SecretKey[] newKeys = new SecretKey[TOKEN_BUFFER_SIZE];
+                for (int i = 0; i < newKeys.length; i++) {
+                    int isNull = keyInputStream.readInt();
+                    if (isNull == 1) {
+                        int l = keyInputStream.readInt();
+                        byte[] b = new byte[l];
+                        keyInputStream.read(b);
+                        newKeys[i] = new SecretKeySpec(b, HMAC_SHA1);
+                    } else {
+                        newKeys[i] = null;
+                    }
+                }
+
+                // assign the tokes and schedule a next update
+                nextUpdate = newNextUpdate;
+                currentToken = newCurrentToken;
+                currentTokens = newKeys;
+
+            } catch (IOException e) {
+
+                log.error("Failed to load cookie keys " + e.getMessage());
+
+            } finally {
+
+                if (keyInputStream != null) {
+                    try {
+                        keyInputStream.close();
+                    } catch (IOException e) {
+                    }
+                } else if (fin != null) {
+                    try {
+                        fin.close();
+                    } catch (IOException e) {
+                    }
+                }
+            }
+        }
+
+        // if there was a failure to read the current tokens, create new ones
+        if (currentTokens == null) {
+            currentTokens = new SecretKey[TOKEN_BUFFER_SIZE];
+            nextUpdate = System.currentTimeMillis();
+            currentToken = 0;
+        }
+    }
+
+    /**
+     * Encode a byte array.
+     *
+     * @param base
+     * @return
+     */
+    private String byteToHex(byte[] base) {
+        char[] c = new char[base.length * 2];
+        int i = 0;
+
+        for (byte b : base) {
+            int j = b;
+            j = j + 128;
+            c[i++] = TOHEX[j / 0x10];
+            c[i++] = TOHEX[j % 0x10];
+        }
+        return new String(c);
+    }
+}
\ No newline at end of file
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
new file mode 100644
index 0000000..1dc9616
--- /dev/null
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -0,0 +1,68 @@
+#
+#  Licensed to the Apache Software Foundation (ASF) under one
+#  or more contributor license agreements.  See the NOTICE file
+#  distributed with this work for additional information
+#  regarding copyright ownership.  The ASF licenses this file
+#  to you under the Apache License, Version 2.0 (the
+#  "License"); you may not use this file except in compliance
+#  with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+#  Unless required by applicable law or agreed to in writing,
+#  software distributed under the License is distributed on an
+#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+#  specific language governing permissions and limitations
+#  under the License.
+#
+
+#
+# This file contains localization strings for configuration labels and
+# descriptions as used in the metatype.xml descriptor generated by the
+# the Sling SCR plugin
+
+auth.form.name=Apache Sling Form Based Authentication Handler
+auth.form.description=This handler extracts a hash value from a cookie or  \
+ session attribute id and compares it to a hash generated on the server.
+
+path.name = Path
+path.description = Repository path for which this authentication handler \
+ should be used by Sling. If this is empty, the authentication handler will \
+ be disabled.
+
+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".
+
+form.auth.storage.name = Hash Storage
+form.auth.storage.description = The type of storage used to provide the \
+ 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". 
+
+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.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 \
+ currently refers to a file stored in the file system. If the path is a \
+ relative path, the file is either stored in the Authentication Handler bundle \
+ private data area or - if not possible - below the location indicated by the \
+ sling.home framework property or - if sling.home is not set - the current \
+ working directory. In the future this file may be store in the JCR Repository \
+ to support clustering scenarios.
diff --git a/src/main/resources/login.html b/src/main/resources/login.html
new file mode 100644
index 0000000..2d3c7a0
--- /dev/null
+++ b/src/main/resources/login.html
@@ -0,0 +1,65 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xml:lang="en" lang="en"
+      xmlns="http://www.w3.org/1999/xhtml"
+>
+<head>
+   <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+   <title>Login</title>
+   
+   <style type="text/css">
+   body {
+       font-family: Verdana, Arial, Helvetica, sans-serif;
+       font-size: 10px;
+       color: black;
+       background-color: white;
+   }
+   
+   #main {
+       border: 1px solid gray;
+       margin-top: 25%;
+       margin-left: 25%;
+       width: 400px;
+       padding: 10px;
+   }
+   
+   #loginform {
+       padding: 0px;
+       margin: 0px;
+   }
+   </style>
+   
+</head>
+
+<body>
+
+<div id="main"><!-- Login Form -->
+<h3>Login:</h3>
+<form id="loginform" method="POST" action="j_security_check"
+        enctype="multipart/form-data" accept-charset="UTF-8">
+
+   <input type="hidden" name="_charset_" value="UTF-8" />
+   <input type="hidden" name="resource" value="${resource}" />
+   
+   <div>
+      <label for="j_username" accesskey="u">User ID:</label>
+   </div>
+   <div>
+      <input id="j_username" name="j_username" type="text" />
+   </div>
+   
+   
+   <div>
+      <label for="j_password" accesskey="p">Password:</label>
+   </div>
+   <div>
+      <input id="j_password" name="j_password" type="password" />
+   </div>
+
+   <div class="buttongroup">
+      <button id="login" accesskey="l" class="form-button" type="submit">Login</button>
+   </div>
+</form>
+</div>
+
+</body>
+</html>
diff --git a/src/test/java/org/apache/sling/formauth/FormAuthenticationHandlerTest.java b/src/test/java/org/apache/sling/formauth/FormAuthenticationHandlerTest.java
new file mode 100644
index 0000000..31e8e21
--- /dev/null
+++ b/src/test/java/org/apache/sling/formauth/FormAuthenticationHandlerTest.java
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.sling.formauth;
+
+import java.io.File;
+
+import junit.framework.TestCase;
+
+import org.hamcrest.Description;
+import org.hamcrest.text.StringStartsWith;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.api.Action;
+import org.jmock.api.Invocation;
+import org.osgi.framework.BundleContext;
+
+public class FormAuthenticationHandlerTest extends TestCase {
+
+    public void test_getTokenFile() {
+        final File root = new File("bundle999").getAbsoluteFile();
+        final SlingHomeAction slingHome = new SlingHomeAction();
+        slingHome.setSlingHome(new File("sling").getAbsolutePath());
+
+        Mockery context = new Mockery();
+        final BundleContext bundleContext = context.mock(BundleContext.class);
+
+        context.checking(new Expectations() {
+            {
+                // mock access to sling.home framework property
+                allowing(bundleContext).getProperty("sling.home");
+                will(slingHome);
+
+                // mock no data file support with file names starting with sl
+                allowing(bundleContext).getDataFile(
+                    with(new StringStartsWith("sl")));
+                will(returnValue(null));
+
+                // mock data file support for any other name
+                allowing(bundleContext).getDataFile(with(any(String.class)));
+                will(new RVA(root));
+            }
+        });
+
+        final FormAuthenticationHandler handler = new FormAuthenticationHandler();
+
+        // test files relative to bundle context
+        File relFile0 = handler.getTokenFile("", bundleContext);
+        assertEquals(root, relFile0);
+
+        String relName1 = "rel/path";
+        File relFile1 = handler.getTokenFile(relName1, bundleContext);
+        assertEquals(new File(root, relName1), relFile1);
+
+        // test file relative to sling.home if no data file support
+        String relName2 = "sl/rel_to_sling.home";
+        File relFile2 = handler.getTokenFile(relName2, bundleContext);
+        assertEquals(new File(slingHome.getSlingHome(), relName2), relFile2);
+
+        // test file relative to current working directory
+        String relName3 = "sl/test";
+        slingHome.setSlingHome(null);
+        File relFile3 = handler.getTokenFile(relName3, bundleContext);
+        assertEquals(new File(relName3).getAbsoluteFile(), relFile3);
+
+        // test absolute file return
+        File absFile = new File("test").getAbsoluteFile();
+        File absFile0 = handler.getTokenFile(absFile.getPath(), bundleContext);
+        assertEquals(absFile, absFile0);
+    }
+
+    public void test_getUserid() {
+        final FormAuthenticationHandler handler = new FormAuthenticationHandler();
+        assertEquals(null, handler.getUserId(null));
+        assertEquals(null, handler.getUserId(""));
+        assertEquals(null, handler.getUserId("field0"));
+        assertEquals(null, handler.getUserId("field0@field1"));
+        assertEquals("field3", handler.getUserId("field0@field1@field3"));
+        assertEquals(null, handler.getUserId("field0@field1@field3@field4"));
+    }
+
+    /**
+     * The <code>RVA</code> action returns a file relative to some root file as
+     * requested by the first parameter of the invocation, expecting the first
+     * parameter to be a string.
+     */
+    private static class RVA implements Action {
+
+        private final File root;
+
+        RVA(final File root) {
+            this.root = root;
+        }
+
+        public Object invoke(Invocation invocation) throws Throwable {
+            String data = (String) invocation.getParameter(0);
+            if (data.startsWith("/")) {
+                data = data.substring(1);
+            }
+            return new File(root, data);
+        }
+
+        public void describeTo(Description description) {
+            description.appendText("returns new File(root, arg0)");
+        }
+    }
+
+    /**
+     * The <code>SlingHomeAction</code> action returns the current value of the
+     * <code>slingHome</code> field on all invocations
+     */
+    private static class SlingHomeAction implements Action {
+        private String slingHome;
+
+        public void setSlingHome(String slingHome) {
+            this.slingHome = slingHome;
+        }
+
+        public String getSlingHome() {
+            return slingHome;
+        }
+
+        public Object invoke(Invocation invocation) throws Throwable {
+            return slingHome;
+        }
+
+        public void describeTo(Description description) {
+            description.appendText("returns " + slingHome);
+        }
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 28/32: Set JIRA version id and fix JavaDoc exclusions

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit 9946c7cf66a0585a3acab9b20589f44294338050
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Mon Aug 23 13:40:01 2010 +0000

    Set JIRA version id and fix JavaDoc exclusions
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form@988119 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 19 ++++++-------------
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/pom.xml b/pom.xml
index 3a8132d..7201953 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,11 @@
         when first authenticating.
     </description>
 
+    <properties>
+        <site.jira.version.id>12314785</site.jira.version.id>
+        <site.javadoc.exclude>**.impl.**</site.javadoc.exclude>
+    </properties>
+
     <scm>
         <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form</connection>
         <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/bundles/auth/form</developerConnection>
@@ -89,19 +94,7 @@
             </plugin>
         </plugins>
     </build>
-    <reporting>
-        <plugins>
-            <plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-javadoc-plugin</artifactId>
-                <configuration>
-                    <excludePackageNames>
-                        org.apache.sling.auth.form
-                    </excludePackageNames>
-                </configuration>
-            </plugin>
-        </plugins>
-    </reporting>
+
     <dependencies>
         <dependency>
             <groupId>org.apache.sling</groupId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-auth-form] 05/32: SLING-1116 Ensure the FormLoginModulePlugin is actually registered as a service (otherwise authenticaiton may fail). Also the resource attribute is set in the extractRequestParameterAuthentication method to ensure a redirect takes place after successful login

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to annotated tag org.apache.sling.auth.form-1.0.0
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-auth-form.git

commit a812358a966a23283ec5a1b4658ff2fbd3fe50f6
Author: Felix Meschberger <fm...@apache.org>
AuthorDate: Thu Feb 11 14:30:31 2010 +0000

    SLING-1116 Ensure the FormLoginModulePlugin is actually registered as a service (otherwise authenticaiton may fail). Also the resource attribute is set in the extractRequestParameterAuthentication method to ensure a redirect takes place after successful login
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk/bundles/extensions/formauth@908994 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/formauth/FormAuthenticationHandler.java  | 41 +++++++++++++++
 .../sling/formauth/FormLoginModulePlugin.java      | 59 +++++++++++++++++++++-
 2 files changed, 99 insertions(+), 1 deletion(-)

diff --git a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
index 5d8ed70..eedca08 100644
--- a/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
+++ b/src/main/java/org/apache/sling/formauth/FormAuthenticationHandler.java
@@ -42,6 +42,7 @@ import org.apache.sling.commons.auth.spi.AuthenticationInfo;
 import org.apache.sling.commons.auth.spi.DefaultAuthenticationFeedbackHandler;
 import org.apache.sling.commons.osgi.OsgiUtil;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -224,11 +225,25 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
      */
     private long sessionTimeout;
 
+    /**
+     * The name of the credentials attribute which is set to the cookie data
+     * to validate.
+     */
     private String attrCookieAuthData;
 
+    /**
+     * The {@link TokenStore} used to persist and check authentication data
+     */
     private TokenStore tokenStore;
 
     /**
+     * The {@link FormLoginModulePlugin} service registration created when
+     * this authentication handler is registered. If the login module plugin
+     * cannot be created this field is set to <code>null</code>.
+     */
+    private ServiceRegistration loginModule;
+
+    /**
      * 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
@@ -554,6 +569,15 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
             if (user != null && pwd != null) {
                 info = new AuthenticationInfo(HttpServletRequest.FORM_AUTH,
                     user, pwd.toCharArray());
+
+                // if this request is providing form credentials, we have to
+                // make sure, that the request is redirected after successful
+                // 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) {
+                    request.setAttribute(Authenticator.LOGIN_RESOURCE, "/");
+                }
             }
         }
 
@@ -661,6 +685,23 @@ public class FormAuthenticationHandler implements AuthenticationHandler,
             componentContext.getBundleContext());
         log.info("Storing tokens in ", tokenFile);
         this.tokenStore = new TokenStore(tokenFile, sessionTimeout);
+
+        this.loginModule = null;
+        try {
+            this.loginModule = FormLoginModulePlugin.register(this,
+                componentContext.getBundleContext());
+        } catch (Throwable t) {
+            log.info("Cannot register FormLoginModulePlugin. This is expected if Sling LoginModulePlugin services are not supported");
+            log.debug("dump", t);
+        }
+    }
+
+    protected void deactivate(
+            @SuppressWarnings("unused") ComponentContext componentContext) {
+        if (loginModule != null) {
+            loginModule.unregister();
+            loginModule = null;
+        }
     }
 
     /**
diff --git a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
index 6e95be2..31ee174 100644
--- a/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
+++ b/src/main/java/org/apache/sling/formauth/FormLoginModulePlugin.java
@@ -19,6 +19,7 @@
 package org.apache.sling.formauth;
 
 import java.security.Principal;
+import java.util.Hashtable;
 import java.util.Map;
 import java.util.Set;
 
@@ -28,12 +29,68 @@ import javax.jcr.SimpleCredentials;
 import javax.security.auth.callback.CallbackHandler;
 import org.apache.sling.jcr.jackrabbit.server.security.AuthenticationPlugin;
 import org.apache.sling.jcr.jackrabbit.server.security.LoginModulePlugin;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
+import org.osgi.framework.ServiceRegistration;
 
+/**
+ * The <code>FormLoginModulePlugin</code> is a LoginModulePlugin which handles
+ * <code>SimpleCredentials</code> attributed with the special authentication
+ * data provided by the {@link FormAuthenticationHandler}.
+ * <p>
+ * This class is instantiated by the {@link FormAuthenticationHandler} calling
+ * the {@link #register(FormAuthenticationHandler, BundleContext)} method. If
+ * the OSGi framework does not provide the <code>LoginModulePlugin</code>
+ * interface (such as when the Sling Jackrabbit Server bundle is not used to
+ * provide the JCR Repository), loading this class fails, which is caught by the
+ * {@link FormAuthenticationHandler}.
+ */
 final class FormLoginModulePlugin implements LoginModulePlugin {
 
+    /**
+     * The {@link FormAuthenticationHandler} used to validate the credentials
+     * and its contents.
+     */
     private final FormAuthenticationHandler authHandler;
 
-    FormLoginModulePlugin(final FormAuthenticationHandler authHandler) {
+    /**
+     * Creates an instance of this class and registers it as a
+     * <code>LoginModulePlugin</code> service to handle login requests with
+     * <code>SimpleCredentials</code> provided by the
+     * {@link FormAuthenticationHandler}.
+     *
+     * @param authHandler The {@link FormAuthenticationHandler} providing
+     *            support to validate the credentials
+     * @param bundleContext The <code>BundleContext</code> to register the
+     *            service
+     * @return The <code>ServiceRegistration</code> of the registered service for
+     *         the {@link FormAuthenticationHandler} to unregister the service
+     *         on shutdown.
+     */
+    static ServiceRegistration register(
+            final FormAuthenticationHandler authHandler,
+            final BundleContext bundleContext) {
+        FormLoginModulePlugin plugin = new FormLoginModulePlugin(authHandler);
+
+        Hashtable<String, Object> properties = new Hashtable<String, Object>();
+        properties.put(Constants.SERVICE_DESCRIPTION,
+            "LoginModulePlugin Support for FormAuthenticationHandler");
+        properties.put(Constants.SERVICE_VENDOR,
+            bundleContext.getBundle().getHeaders().get(Constants.BUNDLE_VENDOR));
+
+        return bundleContext.registerService(LoginModulePlugin.class.getName(),
+            plugin, properties);
+    }
+
+    /**
+     * Private constructor called from
+     * {@link #register(FormAuthenticationHandler, BundleContext)} to create an
+     * instance of this class.
+     *
+     * @param authHandler The {@link FormAuthenticationHandler} used to validate
+     *            the credentials attribute
+     */
+    private FormLoginModulePlugin(final FormAuthenticationHandler authHandler) {
         this.authHandler = authHandler;
     }
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.