You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ju...@apache.org on 2010/06/23 23:30:55 UTC
svn commit: r957356 - in /sling/trunk/bundles/extensions/formauth: ./
src/main/java/org/apache/sling/formauth/impl/
src/main/resources/OSGI-INF/metatype/
Author: justin
Date: Wed Jun 23 21:30:55 2010
New Revision: 957356
URL: http://svn.apache.org/viewvc?rev=957356&view=rev
Log:
SLING-1564 - adding support for form inclusion as well as custom form pages via fragments
Modified:
sling/trunk/bundles/extensions/formauth/pom.xml
sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties
Modified: sling/trunk/bundles/extensions/formauth/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/pom.xml?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/pom.xml (original)
+++ sling/trunk/bundles/extensions/formauth/pom.xml Wed Jun 23 21:30:55 2010
@@ -117,6 +117,12 @@
<scope>provided</scope>
</dependency>
<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.api</artifactId>
+ <version>2.0.9-SNAPSHOT</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
</dependency>
Modified: sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java (original)
+++ sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/AuthenticationFormServlet.java Wed Jun 23 21:30:55 2010
@@ -58,6 +58,10 @@ public class AuthenticationFormServlet e
@SuppressWarnings("unused")
private static final String AUTH_REQUIREMENT = "-" + SERVLET_PATH;
+ private static final String DEFAULT_FORM_PATH = "login.html";
+
+ private static final String CUSTOM_FORM_PATH = "custom_login.html";
+
/**
* The raw form used by the {@link #getForm(HttpServletRequest)} method to
* fill in with per-request data. This field is set by the
@@ -82,7 +86,30 @@ public class AuthenticationFormServlet e
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws IOException {
+ handle(request, response);
+ }
+
+ /**
+ * Prepares and returns the login form. The response is sent as an UTF-8
+ * encoded <code>text/html</code> page with all known cache control headers
+ * set to prevent all caching.
+ * <p>
+ * This servlet is to be called to handle the request directly, that is it
+ * expected to not be included and for the response to not be committed yet
+ * because it first resets the response.
+ *
+ * @throws IOException if an error occurrs preparing or sending back the
+ * login form
+ * @throws IllegalStateException if the response has already been committed
+ * and thus response reset is not possible.
+ */
+ @Override
+ protected void doPost(HttpServletRequest request,
+ HttpServletResponse response) throws IOException {
+ handle(request, response);
+ }
+ private void handle(HttpServletRequest request, HttpServletResponse response) throws IOException {
// reset the response first
response.reset();
@@ -143,6 +170,12 @@ public class AuthenticationFormServlet e
* string if there is no specific reason
*/
private String getReason(final HttpServletRequest request) {
+ // return the resource attribute if set to a non-empty string
+ Object resObj = request.getAttribute(FormAuthenticationHandler.PAR_J_REASON);
+ if (resObj instanceof FormReason) {
+ return ((FormReason) resObj).toString();
+ }
+
final String reason = request.getParameter(FormAuthenticationHandler.PAR_J_REASON);
if (reason != null) {
try {
@@ -150,7 +183,7 @@ public class AuthenticationFormServlet e
} catch (IllegalArgumentException iae) {
// thrown if the reason is not an expected value, assume none
}
-
+
// no valid FormReason value, use raw value
return reason;
}
@@ -169,7 +202,13 @@ public class AuthenticationFormServlet e
if (rawForm == null) {
InputStream ins = null;
try {
- ins = getClass().getResourceAsStream("login.html");
+ // try a custom login page first.
+ ins = getClass().getResourceAsStream(CUSTOM_FORM_PATH);
+ if (ins == null) {
+ // try the standard login page
+ ins = getClass().getResourceAsStream(DEFAULT_FORM_PATH);
+ }
+
if (ins != null) {
StringBuilder builder = new StringBuilder();
Reader r = new InputStreamReader(ins, "UTF-8");
Modified: sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java (original)
+++ sling/trunk/bundles/extensions/formauth/src/main/java/org/apache/sling/formauth/impl/FormAuthenticationHandler.java Wed Jun 23 21:30:55 2010
@@ -28,6 +28,8 @@ import java.util.Dictionary;
import javax.jcr.Credentials;
import javax.jcr.SimpleCredentials;
+import javax.servlet.Servlet;
+import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -35,6 +37,10 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
+import org.apache.sling.api.resource.LoginException;
+import org.apache.sling.api.resource.Resource;
+import org.apache.sling.api.resource.ResourceResolver;
+import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.commons.auth.Authenticator;
import org.apache.sling.commons.auth.spi.AuthenticationFeedbackHandler;
import org.apache.sling.commons.auth.spi.AuthenticationHandler;
@@ -151,6 +157,21 @@ public class FormAuthenticationHandler i
private static final String DEFAULT_TOKEN_FILE = "cookie-tokens.bin";
/**
+ * Whether to redirect to the login form or simple do an include.
+ *
+ * @scr.property type="Boolean" valueRef="DEFAULT_INCLUDE_FORM"
+ */
+ public static final String PAR_INCLUDE_FORM = "form.use.include";
+
+ /**
+ * The default include value.
+ *
+ * @see #PAR_INCLUDE_FORM
+ */
+ private static final boolean DEFAULT_INCLUDE_FORM = false;
+
+
+ /**
* The request method required for user name and password submission by the
* form (value is "POST").
*/
@@ -247,6 +268,20 @@ public class FormAuthenticationHandler i
private ServiceRegistration loginModule;
/**
+ * If true, the handler will attempt to include the login form instead of
+ * doing a redirect.
+ */
+ private boolean includeLoginForm;
+
+ /**
+ * The resource resolver factory used to resolve the login form as a resource
+ *
+ * @scr.reference policy="dynamic" cardinality="0..1"
+ */
+ private ResourceResolverFactory resourceResolverFactory;
+
+
+ /**
* Extracts cookie/session based credentials from the request. Returns
* <code>null</code> if the handler assumes HTTP Basic authentication would
* be more appropriate, if no form fields are present in the request and if
@@ -311,6 +346,35 @@ public class FormAuthenticationHandler i
return true;
}
+ String resource = getLoginResource(request);
+ if (resource == null) {
+ resource = request.getContextPath() + request.getPathInfo();
+ request.setAttribute(Authenticator.LOGIN_RESOURCE, resource);
+ }
+
+ if (includeLoginForm && (resourceResolverFactory != null)) {
+ ResourceResolver resourceResolver = null;
+ try {
+ resourceResolver = resourceResolverFactory.getAdministrativeResourceResolver(null);
+ Resource loginFormResource = resourceResolver.resolve(loginForm);
+ Servlet loginFormServlet = loginFormResource.adaptTo(Servlet.class);
+ if (loginFormServlet != null) {
+ try {
+ loginFormServlet.service(request, response);
+ return true;
+ } catch (ServletException e) {
+ log.error("Failed to include the form: " + loginForm, e);
+ }
+ }
+ } catch (LoginException e) {
+ log.error("Unable to get a resource resolver to include for the login resource. Will redirect instead.");
+ } finally {
+ if (resourceResolver != null) {
+ resourceResolver.close();
+ }
+ }
+ }
+
// prepare the login form redirection target
final StringBuilder targetBuilder = new StringBuilder();
targetBuilder.append(request.getContextPath());
@@ -318,10 +382,6 @@ public class FormAuthenticationHandler i
// append originally requested resource (for redirect after login)
char parSep = '?';
- String resource = getLoginResource(request);
- if (resource == null) {
- resource = request.getContextPath() + request.getPathInfo();
- }
if (resource != null) {
targetBuilder.append(parSep).append(Authenticator.LOGIN_RESOURCE);
@@ -706,6 +766,9 @@ public class FormAuthenticationHandler i
log.info("Cannot register FormLoginModulePlugin. This is expected if Sling LoginModulePlugin services are not supported");
log.debug("dump", t);
}
+
+ this.includeLoginForm = OsgiUtil.toBoolean(properties.get(PAR_INCLUDE_FORM), DEFAULT_INCLUDE_FORM);
+
}
protected void deactivate(
Modified: sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=957356&r1=957355&r2=957356&view=diff
==============================================================================
--- sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties (original)
+++ sling/trunk/bundles/extensions/formauth/src/main/resources/OSGI-INF/metatype/metatype.properties Wed Jun 23 21:30:55 2010
@@ -31,7 +31,7 @@ path.description = Repository path for w
should be used by Sling. If this is empty, the authentication handler will \
be disabled.
-form.login.form.name = Login Form
+form.login.form.name = Login Form
form.login.form.description = The URL (without any context path prefix) to \
redirect the client to to present the login form. The default value is \
"/system/sling/form/login".
@@ -41,22 +41,22 @@ form.auth.storage.description = The type
authentication state. Valid values are cookie and session. The default value \
(cookie) also applies if any setting other than the supported values is \
configured.
-
+
form.auth.name.name = Cookie/Attribute Name
form.auth.name.description = The name of the Cookie or HTTP Session attribute \
- providing the authentication state. The default value is "sling.formauth".
+ providing the authentication state. The default value is "sling.formauth".
-form.credentials.name.name = Credentials Attribute
+form.credentials.name.name = Credentials Attribute
form.credentials.name.description = The name of the SimpleCredentials \
attribute used to provide the authentication data to the LoginModulePlugin. \
The default value is "sling.formauth".
-form.auth.timeout.name = Timeout
+form.auth.timeout.name = Timeout
form.auth.timeout.description = The number of minutes after which a login \
session times out. This value is used as the expiry time set in the \
authentication data. The default value is 30 minutes. If the value is set \
a value less than 1, the default value is used instead.
-
+
form.token.file.name = Security Token File
form.token.file.description = The name of the file used to persist the \
security tokens. The default value is cookie-tokens.bin. This property \
@@ -70,3 +70,7 @@ form.token.file.description = The name o
service.ranking.name = Ranking
service.ranking.description = The relative ranking of this service.
+form.use.include.name = Include Form
+form.use.include.description = If true, this authentication handler will attempt \
+ to include a Servlet resource at the login form path. If false, a redirect will \
+ be used instead.