You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by fm...@apache.org on 2010/02/01 11:57:43 UTC
svn commit: r905248 - in
/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth:
impl/ impl/engine/ spi/
Author: fmeschbe
Date: Mon Feb 1 10:57:43 2010
New Revision: 905248
URL: http://svn.apache.org/viewvc?rev=905248&view=rev
Log:
SLING-1314 Apply proposed patch supporting authentication feedback after trying
to login
Added:
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationFeedbackHandler.java (with props)
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/DefaultAuthenticationFeedbackHandler.java (with props)
Modified:
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AbstractAuthenticationHandlerHolder.java
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AuthenticationHandlerHolder.java
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java
Modified: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AbstractAuthenticationHandlerHolder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AbstractAuthenticationHandlerHolder.java?rev=905248&r1=905247&r2=905248&view=diff
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AbstractAuthenticationHandlerHolder.java (original)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AbstractAuthenticationHandlerHolder.java Mon Feb 1 10:57:43 2010
@@ -23,6 +23,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.sling.commons.auth.spi.AuthenticationFeedbackHandler;
import org.apache.sling.commons.auth.spi.AuthenticationHandler;
import org.apache.sling.commons.auth.spi.AuthenticationInfo;
@@ -38,6 +39,8 @@
super(fullPath);
}
+ protected abstract AuthenticationFeedbackHandler getFeedbackHandler();
+
protected abstract AuthenticationInfo doExtractCredentials(HttpServletRequest request,
HttpServletResponse response);
Modified: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AuthenticationHandlerHolder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AuthenticationHandlerHolder.java?rev=905248&r1=905247&r2=905248&view=diff
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AuthenticationHandlerHolder.java (original)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/AuthenticationHandlerHolder.java Mon Feb 1 10:57:43 2010
@@ -23,6 +23,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.sling.commons.auth.spi.AuthenticationFeedbackHandler;
import org.apache.sling.commons.auth.spi.AuthenticationHandler;
import org.apache.sling.commons.auth.spi.AuthenticationInfo;
@@ -46,6 +47,14 @@
this.handler = handler;
}
+ @Override
+ protected AuthenticationFeedbackHandler getFeedbackHandler() {
+ if (handler instanceof AuthenticationFeedbackHandler) {
+ return (AuthenticationFeedbackHandler) handler;
+ }
+ return null;
+ }
+
public AuthenticationInfo doExtractCredentials(HttpServletRequest request,
HttpServletResponse response) {
Modified: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java?rev=905248&r1=905247&r2=905248&view=diff
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java (original)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/SlingAuthenticator.java Mon Feb 1 10:57:43 2010
@@ -40,8 +40,10 @@
import org.apache.sling.commons.auth.Authenticator;
import org.apache.sling.commons.auth.NoAuthenticationHandlerException;
import org.apache.sling.commons.auth.impl.engine.EngineAuthenticationHandlerHolder;
+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.apache.sling.jcr.api.SlingRepository;
import org.apache.sling.jcr.api.TooManySessionsException;
@@ -145,6 +147,13 @@
*/
private static final String REQUEST_ATTRIBUTE_SESSION = "javax.jcr.Session";
+ /**
+ * The name of the {@link AuthenticationInfo} property providing the option
+ * {@link org.apache.sling.commons.auth.spi.AuthenticationFeedbackHandler}
+ * handler to be called back on login failure or success.
+ */
+ private static final String AUTH_INFO_PROP_FEEDBACK_HANDLER = "$$sling.auth.AuthenticationFeedbackHandler$$";
+
private static ArrayList<AbstractAuthenticationHandlerHolder> EMPTY_INFO = new ArrayList<AbstractAuthenticationHandlerHolder>();
/** @scr.reference */
@@ -491,7 +500,12 @@
if (pathInfo.startsWith(holder.path)) {
final AuthenticationInfo authInfo = holder.extractCredentials(
request, response);
+
if (authInfo != null) {
+ // add the feedback handler to the info (may be null)
+ authInfo.put(AUTH_INFO_PROP_FEEDBACK_HANDLER,
+ holder.getFeedbackHandler());
+
return authInfo;
}
}
@@ -506,6 +520,9 @@
private boolean getSession(final HttpServletRequest request,
final HttpServletResponse response, final AuthenticationInfo authInfo) {
+ // prepare the feedback handler
+ final AuthenticationFeedbackHandler feedbackHandler = (AuthenticationFeedbackHandler) authInfo.remove(AUTH_INFO_PROP_FEEDBACK_HANDLER);
+
// try to connect
try {
Session session = repository.login(authInfo.getCredentials(),
@@ -514,10 +531,25 @@
// handle impersonation
session = handleImpersonation(request, response, session);
- // check whether the client asked for redirect after
- // authentication and/or impersonation
- if (handleRedirect(request, response)) {
- return false;
+ // handle success feedback
+ if (feedbackHandler != null) {
+
+ // call the feedback handler, terminating the request if
+ // so desired by the handler
+ if (feedbackHandler.authenticationSucceeded(request, response,
+ authInfo)) {
+ return false;
+ }
+
+ } else {
+
+ // if there is no feedback handler: check whether the client
+ // asked for redirect after authentication and/or impersonation
+ if (DefaultAuthenticationFeedbackHandler.handleRedirect(
+ request, response)) {
+ return false;
+ }
+
}
// set the attributes for further processing
@@ -527,6 +559,13 @@
} catch (RepositoryException re) {
+ // handle failure feedback before proceeding to handling the
+ // failed login internally
+ if (feedbackHandler != null) {
+ feedbackHandler.authenticationFailed(request, response, authInfo);
+ }
+
+ // now find a way to get credentials
handleLoginFailure(request, response, authInfo.getUser(), re);
}
@@ -550,7 +589,8 @@
// check whether the client asked for redirect after
// authentication and/or impersonation
- if (handleRedirect(request, response)) {
+ if (DefaultAuthenticationFeedbackHandler.handleRedirect(
+ request, response)) {
return false;
}
@@ -860,58 +900,6 @@
}
/**
- * Handles an optional request for a redirect after successful
- * authentication and <code>true</code> if the request has been redirected.
- * <p>
- * If sending the redirect response fails due to some IO problems, the
- * request is still terminated but an error message is logged indicating the
- * problem.
- *
- * @return <code>true</code> if redirect was requested. Otherwise
- * <code>false</code> is returned. Note, that <code>true</code> is
- * returned regardless of whether sending the redirect response
- * succeeded or not.
- */
- private boolean handleRedirect(final HttpServletRequest request,
- final HttpServletResponse response) {
-
- final String redirect = request.getParameter(REDIRECT_PARAMETER);
- if (redirect != null) {
-
- // find the redirect target
- final String target;
- if ("true".equalsIgnoreCase(redirect) || redirect.length() == 0) {
- // redirect to the same path
- target = request.getRequestURI();
-
- } else if (redirect.startsWith("/")) {
- // absolute target (in the servlet context)
- target = request.getContextPath() + redirect;
-
- } else {
- // redirect relative to the current request
- target = redirect;
-
- }
-
- // and redirect ensuring the response is sent to the client
- try {
- response.sendRedirect(target);
- } catch (Exception e) {
- // expected: IOException and IllegalStateException
- log.error("handleRedirect: Failed to send redirect to "
- + target + ", aborting request without redirect", e);
- }
-
- // consider the request done
- return true;
- }
-
- // no redirect requested
- return false;
- }
-
- /**
* Returns the path to be used to select the authentication handler to login
* or logout with.
* <p>
Modified: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java?rev=905248&r1=905247&r2=905248&view=diff
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java (original)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/impl/engine/EngineAuthenticationHandlerHolder.java Mon Feb 1 10:57:43 2010
@@ -24,6 +24,7 @@
import javax.servlet.http.HttpServletResponse;
import org.apache.sling.commons.auth.impl.AbstractAuthenticationHandlerHolder;
+import org.apache.sling.commons.auth.spi.AuthenticationFeedbackHandler;
import org.apache.sling.commons.auth.spi.AuthenticationInfo;
import org.apache.sling.engine.auth.AuthenticationHandler;
@@ -46,6 +47,14 @@
this.handler = handler;
}
+ @Override
+ protected AuthenticationFeedbackHandler getFeedbackHandler() {
+ if (handler instanceof AuthenticationFeedbackHandler) {
+ return (AuthenticationFeedbackHandler) handler;
+ }
+ return null;
+ }
+
public AuthenticationInfo doExtractCredentials(HttpServletRequest request,
HttpServletResponse response) {
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationFeedbackHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationFeedbackHandler.java?rev=905248&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationFeedbackHandler.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationFeedbackHandler.java Mon Feb 1 10:57:43 2010
@@ -0,0 +1,72 @@
+/*
+ * 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.commons.auth.spi;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The <code>AuthenticationFeedbackHandler</code> may be implemented by
+ * {@link AuthenticationHandler} services to request being informed on the
+ * success or failure of authentication.
+ */
+public interface AuthenticationFeedbackHandler {
+
+ /**
+ * Called if authentication failed with the credentials provided in the
+ * <code>authInfo</code> map.
+ * <p>
+ * This method allows the handler to cleanup any state prepared while
+ * handling the
+ * {@link AuthenticationHandler#extractCredentials(HttpServletRequest, HttpServletResponse)
+ * extractCredentials} method. Handlers are expected to not send a in this
+ * method because the Sling Authenticator will proceed to select an
+ * authentication handler whose
+ * {@link AuthenticationHandler#requestCredentials(HttpServletRequest, HttpServletResponse)
+ * requestCredentials} method will be called.
+ *
+ * @param request The current request
+ * @param response The current response
+ * @param authInfo The {@link AuthenticationInfo} object used to
+ * authenticate the request.
+ */
+ void authenticationFailed(HttpServletRequest request,
+ HttpServletResponse response, AuthenticationInfo authInfo);
+
+ /**
+ * Called if authentication succeeded with the credentials provided in the
+ * <code>authInfo</code> map.
+ * <p>
+ * This method is called after successful login and impersonation handling
+ * immediately before continuing with the request. The handler may choose to
+ * send its own response or to just set some response header (e.g. adding a
+ * Cookie) and return appropriately.
+ *
+ * @param request The current request
+ * @param response The current response
+ * @param authInfo The {@link AuthenticationInfo} object used to
+ * authenticate the request.
+ * @return <code>true</code> if the handler sent back a response to the
+ * client and request processing should be terminated at this point.
+ * If <code>false</code> is returned, the request proceeds as
+ * authenticated.
+ */
+ boolean authenticationSucceeded(HttpServletRequest request,
+ HttpServletResponse response, AuthenticationInfo authInfo);
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationFeedbackHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/AuthenticationFeedbackHandler.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url
Added: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/DefaultAuthenticationFeedbackHandler.java
URL: http://svn.apache.org/viewvc/sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/DefaultAuthenticationFeedbackHandler.java?rev=905248&view=auto
==============================================================================
--- sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/DefaultAuthenticationFeedbackHandler.java (added)
+++ sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/DefaultAuthenticationFeedbackHandler.java Mon Feb 1 10:57:43 2010
@@ -0,0 +1,110 @@
+/*
+ * 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.commons.auth.spi;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.commons.auth.AuthenticationSupport;
+import org.slf4j.LoggerFactory;
+
+public class DefaultAuthenticationFeedbackHandler implements
+ AuthenticationFeedbackHandler {
+
+ /**
+ * Handles an optional request for a redirect after successful
+ * authentication and <code>true</code> if the request has been redirected.
+ * <p>
+ * If sending the redirect response fails due to some IO problems, the
+ * request is still terminated but an error message is logged indicating the
+ * problem.
+ *
+ * @return <code>true</code> if redirect was requested. Otherwise
+ * <code>false</code> is returned. Note, that <code>true</code> is
+ * returned regardless of whether sending the redirect response
+ * succeeded or not.
+ */
+ public static boolean handleRedirect(final HttpServletRequest request,
+ final HttpServletResponse response) {
+
+ final String redirect = request.getParameter(AuthenticationSupport.REDIRECT_PARAMETER);
+ if (redirect != null) {
+
+ // find the redirect target
+ final String target;
+ if ("true".equalsIgnoreCase(redirect) || redirect.length() == 0) {
+ // redirect to the same path
+ target = request.getRequestURI();
+
+ } else if (redirect.startsWith("/")) {
+ // absolute target (in the servlet context)
+ target = request.getContextPath() + redirect;
+
+ } else {
+ // redirect relative to the current request
+ target = redirect;
+
+ }
+
+ // and redirect ensuring the response is sent to the client
+ try {
+ response.sendRedirect(target);
+ } catch (Exception e) {
+ // expected: IOException and IllegalStateException
+ LoggerFactory.getLogger(
+ DefaultAuthenticationFeedbackHandler.class).error(
+ "handleRedirect: Failed to send redirect to " + target
+ + ", aborting request without redirect", e);
+ }
+
+ // consider the request done
+ return true;
+ }
+
+ // no redirect requested
+ return false;
+ }
+
+ /**
+ * This default implementation does nothing.
+ * <p>
+ * Extensions of this class may overwrite to cleanup any internal state.
+ */
+ public void authenticationFailed(HttpServletRequest request,
+ HttpServletResponse response, AuthenticationInfo authInfo) {
+ }
+
+ /**
+ * This default implementation calls the
+ * {@link #handleRedirect(HttpServletRequest, HttpServletResponse)} method
+ * to optionally redirect the request after successful authentication.
+ * <p>
+ * Extensions of this class may overwrite this method to perform additional
+ * cleanup etc.
+ *
+ * @param the result of calling the
+ * {@link #handleRedirect(HttpServletRequest, HttpServletResponse)}
+ * method.
+ */
+ public boolean authenticationSucceeded(HttpServletRequest request,
+ HttpServletResponse response, AuthenticationInfo authInfo) {
+ return handleRedirect(request, response);
+ }
+
+}
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/DefaultAuthenticationFeedbackHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: sling/trunk/bundles/commons/auth/src/main/java/org/apache/sling/commons/auth/spi/DefaultAuthenticationFeedbackHandler.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev Url