From a8215fa2cb7355613afd0dda854f371ebe569740 Mon Sep 17 00:00:00 2001
From: Luke Taylor This interceptor is responsible for processing portlet authentication requests. This
- * is the portlet equivalent of the AuthenticationProcessingFilter
used for
+ * is the portlet equivalent of the UsernamePasswordAuthenticationProcessingFilter
used for
* traditional servlet-based web applications. It is applied to both ActionRequest
s
* and RenderRequest
s alike. If authentication is successful, the resulting
* {@link Authentication} object will be placed into the SecurityContext
, which
* is guaranteed to have already been created by an earlier interceptor. If authentication
* fails, the AuthenticationException
will be placed into the
* APPLICATION_SCOPE
of the PortletSession
with the attribute defined
- * by {@link AbstractProcessingFilter#SPRING_SECURITY_LAST_EXCEPTION_KEY}.
Some portals do not properly provide the identity of the current user via the
* The security context contains: " +
SecurityContextHolder.getContext().getAuthentication() +
"
*
* Implementations should modify the headers on the
+ * This filter will intercept a request and attempt to perform authentication from that request if
+ * the request URL matches the value of the filterProcessesUrl property. This behaviour can modified by
+ * overriding the method {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse) requiresAuthentication}.
+ *
+ * Authentication is performed by the {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse)
+ * attemptAuthentication} method, which must be implemented by subclasses.
+ *
+ *
+ * See the {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
+ * successfulAuthentication} method for more information.
+ *
+ *
+ * The filter has an optional attribute invalidateSessionOnSuccessfulAuthentication that will invalidate
+ * the current session on successful authentication. This is to protect against session fixation attacks (see
+ * this Wikipedia article for more information).
+ * The behaviour is turned off by default. Additionally there is a property migrateInvalidatedSessionAttributes
+ * which tells if on session invalidation we are to migrate all session attributes from the old session to a newly
+ * created one. This is turned on by default, but not used unless invalidateSessionOnSuccessfulAuthentication
+ * is true. If you are using this feature in combination with concurrent session control, you should set the
+ * sessionRegistry property to make sure that the session information is updated consistently.
+ *
+ * @author Ben Alex
+ * @version $Id$
+ */
+public abstract class AbstractAuthenticationProcessingFilter extends SpringSecurityFilter implements InitializingBean,
+ ApplicationEventPublisherAware, MessageSourceAware {
+ //~ Static fields/initializers =====================================================================================
+
+ public static final String SPRING_SECURITY_LAST_EXCEPTION_KEY = "SPRING_SECURITY_LAST_EXCEPTION";
+
+ //~ Instance fields ================================================================================================
+
+ protected ApplicationEventPublisher eventPublisher;
+ protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
+ private AuthenticationManager authenticationManager;
+ protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
+
+ /*
+ * Delay use of NullRememberMeServices until initialization so that namespace has a chance to inject
+ * the RememberMeServices implementation into custom implementations.
+ */
+ private RememberMeServices rememberMeServices = null;
+
+ /**
+ * The URL destination that this filter intercepts and processes (usually
+ * something like
+ * It strips any parameters from the "path" section of the request URL (such
+ * as the jsessionid parameter in
+ * http://host/myapp/index.html;jsessionid=blah) before matching
+ * against the
+ * Subclasses may override for special requirements, such as Tapestry integration.
+ *
+ * @return
+ * The implementation should do one of the following:
+ *
- * This filter will intercept a request and attempt to perform authentication from that request if
- * the request URL matches the value of the filterProcessesUrl property. This behaviour can modified by
- * overriding the method {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse) requiresAuthentication}.
- *
- * Authentication is performed by the {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse)
- * attemptAuthentication} method, which must be implemented by subclasses.
+ * See {@link AbstractAuthenticationProcessingFilter}.
*
- *
- * See the {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
- * successfulAuthentication} method for more information.
- *
- *
- * The filter has an optional attribute invalidateSessionOnSuccessfulAuthentication that will invalidate
- * the current session on successful authentication. This is to protect against session fixation attacks (see
- * this Wikipedia article for more information).
- * The behaviour is turned off by default. Additionally there is a property migrateInvalidatedSessionAttributes
- * which tells if on session invalidation we are to migrate all session attributes from the old session to a newly
- * created one. This is turned on by default, but not used unless invalidateSessionOnSuccessfulAuthentication
- * is true. If you are using this feature in combination with concurrent session control, you should set the
- * sessionRegistry property to make sure that the session information is updated consistently.
- *
- * @author Ben Alex
+ * @author Luke Taylor
* @version $Id$
+ * @deprecated Use AbstractAuthenticationProcessingFilter instead.
*/
-public abstract class AbstractProcessingFilter extends SpringSecurityFilter implements InitializingBean,
- ApplicationEventPublisherAware, MessageSourceAware {
- //~ Static fields/initializers =====================================================================================
+@Deprecated
+public abstract class AbstractProcessingFilter extends AbstractAuthenticationProcessingFilter {
- public static final String SPRING_SECURITY_LAST_EXCEPTION_KEY = "SPRING_SECURITY_LAST_EXCEPTION";
-
- //~ Instance fields ================================================================================================
-
- protected ApplicationEventPublisher eventPublisher;
- protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
- private AuthenticationManager authenticationManager;
- protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
-
- /*
- * Delay use of NullRememberMeServices until initialization so that namespace has a chance to inject
- * the RememberMeServices implementation into custom implementations.
- */
- private RememberMeServices rememberMeServices = null;
-
- /**
- * The URL destination that this filter intercepts and processes (usually
- * something like
- * It strips any parameters from the "path" section of the request URL (such
- * as the jsessionid parameter in
- * http://host/myapp/index.html;jsessionid=blah) before matching
- * against the
- * Subclasses may override for special requirements, such as Tapestry integration.
- *
- * @return
- * The implementation should do one of the following:
- *
- * Login forms must present two parameters to this filter: a username and
- * password. The default parameter names to use are contained in the
- * static fields {@link #SPRING_SECURITY_FORM_USERNAME_KEY} and {@link #SPRING_SECURITY_FORM_PASSWORD_KEY}.
- * The parameter names can also be changed by setting the usernameParameter and passwordParameter
- * properties.
- *
- * This filter by default responds to the URL /j_spring_security_check.
+ * See {@link UsernamePasswordAuthenticationProcessingFilter}.
*
- * @author Ben Alex
- * @author Colin Sampaleanu
+ * @author Luke Taylor
* @version $Id$
+ * @deprecated Use UsernamePasswordAuthenticationProcessingFilter instead.
*/
-public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
- //~ Static fields/initializers =====================================================================================
- public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
- public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
- public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
+public class AuthenticationProcessingFilter extends UsernamePasswordAuthenticationProcessingFilter {
- private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
- private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
- private boolean postOnly = true;
-
- //~ Constructors ===================================================================================================
-
- public AuthenticationProcessingFilter() {
- super("/j_spring_security_check");
- }
-
- //~ Methods ========================================================================================================
-
- public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
- if (postOnly && !request.getMethod().equals("POST")) {
- throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
- }
-
- String username = obtainUsername(request);
- String password = obtainPassword(request);
-
- if (username == null) {
- username = "";
- }
-
- if (password == null) {
- password = "";
- }
-
- username = username.trim();
-
- UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
-
- // Place the last username attempted into HttpSession for views
- HttpSession session = request.getSession(false);
-
- if (session != null || getAllowSessionCreation()) {
- request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
- }
-
- // Allow subclasses to set the "details" property
- setDetails(request, authRequest);
-
- return this.getAuthenticationManager().authenticate(authRequest);
- }
-
- /**
- * Enables subclasses to override the composition of the password, such as by including additional values
- * and a separator. This might be used for example if a postcode/zipcode was required in addition to the
- * password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
- *
- * Defaults to true but may be overridden by subclasses.
- */
- public void setPostOnly(boolean postOnly) {
- this.postOnly = postOnly;
- }
-
- public int getOrder() {
- return FilterChainOrder.AUTHENTICATION_PROCESSING_FILTER;
- }
-
- public final String getUsernameParameter() {
- return usernameParameter;
- }
-
- public final String getPasswordParameter() {
- return passwordParameter;
- }
}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPoint.java b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPoint.java
index e01679f2ce..be8c4d5f4a 100644
--- a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPoint.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPoint.java
@@ -1,258 +1,14 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed 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.springframework.security.web.authentication;
-
-
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.web.AuthenticationEntryPoint;
-import org.springframework.security.web.PortMapper;
-import org.springframework.security.web.PortMapperImpl;
-import org.springframework.security.web.PortResolver;
-import org.springframework.security.web.PortResolverImpl;
-import org.springframework.security.web.access.ExceptionTranslationFilter;
-import org.springframework.security.web.util.RedirectUrlBuilder;
-import org.springframework.security.web.util.UrlUtils;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
-import org.springframework.beans.factory.InitializingBean;
-
-import org.springframework.util.Assert;
-import org.springframework.util.StringUtils;
-
-import java.io.IOException;
-
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
/**
- * Used by the {@link ExceptionTranslationFilter} to commence a form login
- * authentication via the {@link AuthenticationProcessingFilter}. This object
- * holds the location of the login form, relative to the web app context path,
- * and is used to commence a redirect to that form.
+ * Renamed class, retained for backwards compatibility.
*
- * By setting the forceHttps property to true, you may configure the
- * class to force the protocol used for the login form to be
+ * In the pre-authenticated authentication case (unlike CAS, for example) the
+ * user will already have been identified through some external mechanism and a
+ * secure context established by the time the security-enforcement filter is
+ * invoked.
+ *
+ * Therefore this class isn't actually responsible for the commencement of
+ * authentication, as it is in the case of other providers. It will be called if
+ * the user is rejected by the AbstractPreAuthenticatedProcessingFilter,
+ * resulting in a null authentication.
+ *
+ * The
+ * By setting the forceHttps property to true, you may configure the
+ * class to force the protocol used for the login form to be
- * Spring Security filters (namely {@link org.springframework.security.web.authentication.AbstractProcessingFilter} and
+ * Spring Security filters (namely {@link org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter} and
* {@link RememberMeProcessingFilter} will call the methods provided by an implementation of this interface.
*
* Implementations may implement any type of remember-me capability they wish.
diff --git a/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationProcessingFilter.java
new file mode 100644
index 0000000000..3adefb03a3
--- /dev/null
+++ b/web/src/main/java/org/springframework/security/web/authentication/UsernamePasswordAuthenticationProcessingFilter.java
@@ -0,0 +1,185 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed 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.springframework.security.web.authentication;
+
+
+import org.springframework.security.authentication.AuthenticationServiceException;
+import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+
+import org.springframework.security.web.FilterChainOrder;
+import org.springframework.security.web.util.TextEscapeUtils;
+import org.springframework.util.Assert;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+
+/**
+ * Processes an authentication form. Called AuthenticationProcessingFilter in previous versions
+ * of the framework.
+ *
+ * Login forms must present two parameters to this filter: a username and
+ * password. The default parameter names to use are contained in the
+ * static fields {@link #SPRING_SECURITY_FORM_USERNAME_KEY} and {@link #SPRING_SECURITY_FORM_PASSWORD_KEY}.
+ * The parameter names can also be changed by setting the usernameParameter and passwordParameter
+ * properties.
+ *
+ * This filter by default responds to the URL /j_spring_security_check.
+ *
+ * @author Ben Alex
+ * @author Colin Sampaleanu
+ * @author Luke Taylor
+ * @version $Id$
+ * @since 3.0
+ */
+public class UsernamePasswordAuthenticationProcessingFilter extends AbstractAuthenticationProcessingFilter {
+ //~ Static fields/initializers =====================================================================================
+
+ public static final String SPRING_SECURITY_FORM_USERNAME_KEY = "j_username";
+ public static final String SPRING_SECURITY_FORM_PASSWORD_KEY = "j_password";
+ public static final String SPRING_SECURITY_LAST_USERNAME_KEY = "SPRING_SECURITY_LAST_USERNAME";
+
+ private String usernameParameter = SPRING_SECURITY_FORM_USERNAME_KEY;
+ private String passwordParameter = SPRING_SECURITY_FORM_PASSWORD_KEY;
+ private boolean postOnly = true;
+
+ //~ Constructors ===================================================================================================
+
+ public UsernamePasswordAuthenticationProcessingFilter() {
+ super("/j_spring_security_check");
+ }
+
+ //~ Methods ========================================================================================================
+
+ public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
+ if (postOnly && !request.getMethod().equals("POST")) {
+ throw new AuthenticationServiceException("Authentication method not supported: " + request.getMethod());
+ }
+
+ String username = obtainUsername(request);
+ String password = obtainPassword(request);
+
+ if (username == null) {
+ username = "";
+ }
+
+ if (password == null) {
+ password = "";
+ }
+
+ username = username.trim();
+
+ UsernamePasswordAuthenticationToken authRequest = new UsernamePasswordAuthenticationToken(username, password);
+
+ // Place the last username attempted into HttpSession for views
+ HttpSession session = request.getSession(false);
+
+ if (session != null || getAllowSessionCreation()) {
+ request.getSession().setAttribute(SPRING_SECURITY_LAST_USERNAME_KEY, TextEscapeUtils.escapeEntities(username));
+ }
+
+ // Allow subclasses to set the "details" property
+ setDetails(request, authRequest);
+
+ return this.getAuthenticationManager().authenticate(authRequest);
+ }
+
+ /**
+ * Enables subclasses to override the composition of the password, such as by including additional values
+ * and a separator. This might be used for example if a postcode/zipcode was required in addition to the
+ * password. A delimiter such as a pipe (|) should be used to separate the password and extended value(s). The
+ *
+ * Defaults to true but may be overridden by subclasses.
+ */
+ public void setPostOnly(boolean postOnly) {
+ this.postOnly = postOnly;
+ }
+
+ public int getOrder() {
+ return FilterChainOrder.AUTHENTICATION_PROCESSING_FILTER;
+ }
+
+ public final String getUsernameParameter() {
+ return usernameParameter;
+ }
+
+ public final String getPasswordParameter() {
+ return passwordParameter;
+ }
+}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java
index 8e16bcbf93..6b2a48a06e 100755
--- a/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/preauth/AbstractPreAuthenticatedProcessingFilter.java
@@ -8,7 +8,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.web.SpringSecurityFilter;
-import org.springframework.security.web.authentication.AbstractProcessingFilter;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.security.authentication.AuthenticationDetailsSource;
import org.springframework.security.authentication.AuthenticationManager;
@@ -128,7 +128,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends SpringSec
if (logger.isDebugEnabled()) {
logger.debug("Cleared security context due to exception", failed);
}
- request.getSession().setAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
+ request.getSession().setAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
}
/**
diff --git a/web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPoint.java b/web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPoint.java
old mode 100755
new mode 100644
index 2b52bd92e8..d64a1e5561
--- a/web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPoint.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPoint.java
@@ -1,65 +1,16 @@
-package org.springframework.security.web.authentication.preauth;
-
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.web.AuthenticationEntryPoint;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.springframework.core.Ordered;
-
-/**
- *
- * In the pre-authenticated authentication case (unlike CAS, for example) the
- * user will already have been identified through some external mechanism and a
- * secure context established by the time the security-enforcement filter is
- * invoked.
- *
- * Therefore this class isn't actually responsible for the commencement of
- * authentication, as it is in the case of other providers. It will be called if
- * the user is rejected by the AbstractPreAuthenticatedProcessingFilter,
- * resulting in a null authentication.
- *
- * The
- * This code is based on
- * {@link org.springframework.security.ui.x509.X509ProcessingFilterEntryPoint}.
- *
- * @see org.springframework.security.web.access.ExceptionTranslationFilter
- *
- * @author Luke Taylor
- * @author Ruud Senden
- * @since 2.0
- */
-public class PreAuthenticatedProcessingFilterEntryPoint implements AuthenticationEntryPoint, Ordered {
- private static final Log logger = LogFactory.getLog(PreAuthenticatedProcessingFilterEntryPoint.class);
-
- private int order = Integer.MAX_VALUE;
-
- /**
- * Always returns a 403 error code to the client.
- */
- public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException,
- ServletException {
- if (logger.isDebugEnabled()) {
- logger.debug("Pre-authenticated entry point called. Rejecting access");
- }
- HttpServletResponse httpResponse = (HttpServletResponse) response;
- httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
- }
-
- public int getOrder() {
- return order;
- }
-
- public void setOrder(int i) {
- order = i;
- }
-
-}
+package org.springframework.security.web.authentication.preauth;
+
+import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
+
+/**
+ * Renamed class, retained for backwards compatibility.
+ *
+ * See {@link Http403ForbiddenEntryPoint}.
+ *
+ * @author Luke Taylor
+ * @version $Id$
+ * @deprecated Use Http403ForbiddenEntryPoint instead.
+ */
+public class PreAuthenticatedProcessingFilterEntryPoint extends Http403ForbiddenEntryPoint {
+
+}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java
index 66002a006e..0791c217c4 100644
--- a/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/ui/DefaultLoginPageGeneratingFilter.java
@@ -12,8 +12,8 @@ import org.springframework.beans.BeanWrapperImpl;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.FilterChainOrder;
import org.springframework.security.web.SpringSecurityFilter;
-import org.springframework.security.web.authentication.AbstractProcessingFilter;
-import org.springframework.security.web.authentication.AuthenticationProcessingFilter;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
+import org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
/**
@@ -39,19 +39,19 @@ public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter {
private String openIDusernameParameter;
private String openIDrememberMeParameter;
- public DefaultLoginPageGeneratingFilter(AbstractProcessingFilter filter) {
- if (filter instanceof AuthenticationProcessingFilter) {
- init((AuthenticationProcessingFilter)filter, null);
+ public DefaultLoginPageGeneratingFilter(AbstractAuthenticationProcessingFilter filter) {
+ if (filter instanceof UsernamePasswordAuthenticationProcessingFilter) {
+ init((UsernamePasswordAuthenticationProcessingFilter)filter, null);
} else {
init(null, filter);
}
}
- public DefaultLoginPageGeneratingFilter(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
+ public DefaultLoginPageGeneratingFilter(UsernamePasswordAuthenticationProcessingFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) {
init(authFilter, openIDFilter);
}
- private void init(AuthenticationProcessingFilter authFilter, AbstractProcessingFilter openIDFilter) {
+ private void init(UsernamePasswordAuthenticationProcessingFilter authFilter, AbstractAuthenticationProcessingFilter openIDFilter) {
if (authFilter != null) {
formLoginEnabled = true;
authenticationUrl = authFilter.getFilterProcessesUrl();
@@ -96,8 +96,8 @@ public class DefaultLoginPageGeneratingFilter extends SpringSecurityFilter {
HttpSession session = request.getSession(false);
if(session != null) {
- lastUser = (String) session.getAttribute(AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY);
- AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
+ lastUser = (String) session.getAttribute(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY);
+ AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY);
errorMsg = ex != null ? ex.getMessage() : "none";
if (lastUser == null) {
lastUser = "";
diff --git a/web/src/main/java/org/springframework/security/web/savedrequest/SavedRequest.java b/web/src/main/java/org/springframework/security/web/savedrequest/SavedRequest.java
index 757ba86200..2e313b0b29 100644
--- a/web/src/main/java/org/springframework/security/web/savedrequest/SavedRequest.java
+++ b/web/src/main/java/org/springframework/security/web/savedrequest/SavedRequest.java
@@ -35,7 +35,7 @@ import java.util.TreeMap;
/**
* Represents central information from a This class is used by {@link
- * org.springframework.security.web.authentication.AbstractProcessingFilter} and {@link org.springframework.security.web.wrapper.SavedRequestAwareWrapper} to
+ * org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter} and {@link org.springframework.security.web.wrapper.SavedRequestAwareWrapper} to
* reproduce the request after successful authentication. An instance of this class is stored at the time of an
* authentication exception by {@link org.springframework.security.web.access.ExceptionTranslationFilter}. IMPLEMENTATION NOTE: It is assumed that this object is accessed only from the context of a single
diff --git a/web/src/main/java/org/springframework/security/web/util/RedirectUtils.java b/web/src/main/java/org/springframework/security/web/util/RedirectUtils.java
index 54b57d105a..ab87d1e4c5 100644
--- a/web/src/main/java/org/springframework/security/web/util/RedirectUtils.java
+++ b/web/src/main/java/org/springframework/security/web/util/RedirectUtils.java
@@ -1,6 +1,6 @@
package org.springframework.security.web.util;
-import org.springframework.security.web.authentication.AbstractProcessingFilter;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter;
import javax.servlet.http.HttpServletRequest;
@@ -20,7 +20,7 @@ public abstract class RedirectUtils {
//~ Methods ========================================================================================================
/**
- * Encapsulates the redirect logic used in classes like {@link AbstractProcessingFilter} and {@link LogoutFilter}.
+ * Encapsulates the redirect logic used in classes like {@link AbstractAuthenticationProcessingFilter} and {@link LogoutFilter}.
*
* @param request the incoming request
* @param response the response to redirect
@@ -28,7 +28,7 @@ public abstract class RedirectUtils {
* @param useRelativeContext if true, causes any redirection URLs to be calculated minus the protocol
* and context path.
*
- * @see AbstractProcessingFilter#setUseRelativeContext(boolean)
+ * @see AbstractAuthenticationProcessingFilter#setUseRelativeContext(boolean)
*/
public static final void sendRedirect(HttpServletRequest request,
HttpServletResponse response,
diff --git a/web/src/test/java/org/springframework/security/web/authentication/AbstractProcessingFilterTests.java b/web/src/test/java/org/springframework/security/web/authentication/AbstractProcessingFilterTests.java
index b1d3dceaff..65a2698472 100644
--- a/web/src/test/java/org/springframework/security/web/authentication/AbstractProcessingFilterTests.java
+++ b/web/src/test/java/org/springframework/security/web/authentication/AbstractProcessingFilterTests.java
@@ -44,7 +44,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.PortResolverImpl;
-import org.springframework.security.web.authentication.AbstractProcessingFilter;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.ExceptionMappingAuthenticationFailureHandler;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
import org.springframework.security.web.authentication.SimpleUrlAuthenticationFailureHandler;
@@ -53,7 +53,7 @@ import org.springframework.security.web.savedrequest.SavedRequest;
/**
- * Tests {@link AbstractProcessingFilter}.
+ * Tests {@link AbstractAuthenticationProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
@@ -191,7 +191,7 @@ public class AbstractProcessingFilterTests extends TestCase {
}
public void testGettersSetters() throws Exception {
- AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
+ AbstractAuthenticationProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setAuthenticationManager(mock(AuthenticationManager.class));
filter.setFilterProcessesUrl("/p");
filter.afterPropertiesSet();
@@ -254,7 +254,7 @@ public class AbstractProcessingFilterTests extends TestCase {
}
public void testStartupDetectsInvalidAuthenticationManager() throws Exception {
- AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
+ AbstractAuthenticationProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setAuthenticationFailureHandler(failureHandler);
successHandler.setDefaultTargetUrl("/");
filter.setAuthenticationSuccessHandler(successHandler);
@@ -269,7 +269,7 @@ public class AbstractProcessingFilterTests extends TestCase {
}
public void testStartupDetectsInvalidFilterProcessesUrl() throws Exception {
- AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
+ AbstractAuthenticationProcessingFilter filter = new MockAbstractProcessingFilter();
filter.setAuthenticationFailureHandler(failureHandler);
filter.setAuthenticationManager(mock(AuthenticationManager.class));
filter.setAuthenticationSuccessHandler(successHandler);
@@ -520,7 +520,7 @@ public class AbstractProcessingFilterTests extends TestCase {
//~ Inner Classes ==================================================================================================
- private class MockAbstractProcessingFilter extends AbstractProcessingFilter {
+ private class MockAbstractProcessingFilter extends AbstractAuthenticationProcessingFilter {
private AuthenticationException exceptionToThrow;
private boolean grantAccess;
diff --git a/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPointTests.java b/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPointTests.java
index 149f87cb91..f9d0d0ab30 100644
--- a/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPointTests.java
+++ b/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterEntryPointTests.java
@@ -20,7 +20,7 @@ import junit.framework.TestCase;
import org.springframework.security.MockPortResolver;
import org.springframework.security.web.PortMapperImpl;
-import org.springframework.security.web.authentication.AuthenticationProcessingFilterEntryPoint;
+import org.springframework.security.web.authentication.LoginUrlAuthenticationEntryPoint;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -30,7 +30,7 @@ import java.util.Map;
/**
- * Tests {@link AuthenticationProcessingFilterEntryPoint}.
+ * Tests {@link LoginUrlAuthenticationEntryPoint}.
*
* @author Ben Alex
* @author colin sampaleanu
@@ -40,7 +40,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
//~ Methods ========================================================================================================
public void testDetectsMissingLoginFormUrl() throws Exception {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
@@ -52,7 +52,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
}
public void testDetectsMissingPortMapper() throws Exception {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("xxx");
ep.setPortMapper(null);
@@ -64,7 +64,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
}
public void testDetectsMissingPortResolver() throws Exception {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("xxx");
ep.setPortResolver(null);
@@ -76,7 +76,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
}
public void testGettersSetters() {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(8080, 8443));
@@ -100,7 +100,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
MockHttpServletResponse response = new MockHttpServletResponse();
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
@@ -129,7 +129,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
portMapper.setPortMappings(map);
response = new MockHttpServletResponse();
- ep = new AuthenticationProcessingFilterEntryPoint();
+ ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
@@ -151,7 +151,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
MockHttpServletResponse response = new MockHttpServletResponse();
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setForceHttps(true);
@@ -170,7 +170,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
}
public void testNormalOperation() throws Exception {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortMapper(new PortMapperImpl());
ep.setPortResolver(new MockPortResolver(80, 443));
@@ -191,7 +191,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
}
public void testOperationWhenHttpsRequestsButHttpsPortUnknown() throws Exception {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setPortResolver(new MockPortResolver(8888, 1234));
ep.setForceHttps(true);
@@ -214,7 +214,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
}
public void testServerSideRedirectWithoutForceHttpsForwardsToLoginPage() throws Exception {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setUseForward(true);
ep.afterPropertiesSet();
@@ -234,7 +234,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
}
public void testServerSideRedirectWithForceHttpsRedirectsCurrentRequest() throws Exception {
- AuthenticationProcessingFilterEntryPoint ep = new AuthenticationProcessingFilterEntryPoint();
+ LoginUrlAuthenticationEntryPoint ep = new LoginUrlAuthenticationEntryPoint();
ep.setLoginFormUrl("/hello");
ep.setUseForward(true);
ep.setForceHttps(true);
diff --git a/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterTests.java b/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterTests.java
index 64f3b3027e..e435cb9e64 100644
--- a/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterTests.java
+++ b/web/src/test/java/org/springframework/security/web/authentication/AuthenticationProcessingFilterTests.java
@@ -35,7 +35,7 @@ import org.springframework.security.core.AuthenticationException;
/**
- * Tests {@link AuthenticationProcessingFilter}.
+ * Tests {@link UsernamePasswordAuthenticationProcessingFilter}.
*
* @author Ben Alex
* @version $Id$
@@ -46,10 +46,10 @@ public class AuthenticationProcessingFilterTests extends TestCase {
@Test
public void testNormalOperation() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
- request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
- request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
+ request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
+ request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
- AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+ UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
assertEquals("/j_spring_security_check", filter.getFilterProcessesUrl());
filter.setAuthenticationManager(createAuthenticationManager());
filter.init(null);
@@ -57,16 +57,16 @@ public class AuthenticationProcessingFilterTests extends TestCase {
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
assertTrue(result != null);
assertEquals("rod", request.getSession().getAttribute(
- AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
+ UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress());
}
@Test
public void testNullPasswordHandledGracefully() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
- request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
+ request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
- AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+ UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
filter.setAuthenticationManager(createAuthenticationManager());
assertNotNull(filter.attemptAuthentication(request, new MockHttpServletResponse()));
}
@@ -74,16 +74,16 @@ public class AuthenticationProcessingFilterTests extends TestCase {
@Test
public void testNullUsernameHandledGracefully() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
- request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
+ request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
- AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+ UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
filter.setAuthenticationManager(createAuthenticationManager());
assertNotNull(filter.attemptAuthentication(request, new MockHttpServletResponse()));
}
@Test
public void testUsingDifferentParameterNamesWorksAsExpected() throws ServletException {
- AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+ UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
filter.setAuthenticationManager(createAuthenticationManager());
filter.setUsernameParameter("x");
filter.setPasswordParameter("y");
@@ -100,10 +100,10 @@ public class AuthenticationProcessingFilterTests extends TestCase {
@Test
public void testSpacesAreTrimmedCorrectlyFromUsername() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
- request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, " rod ");
- request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
+ request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, " rod ");
+ request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_PASSWORD_KEY, "koala");
- AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+ UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
filter.setAuthenticationManager(createAuthenticationManager());
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
@@ -113,8 +113,8 @@ public class AuthenticationProcessingFilterTests extends TestCase {
@Test
public void testFailedAuthenticationThrowsException() {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/");
- request.addParameter(AuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
- AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+ request.addParameter(UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_FORM_USERNAME_KEY, "rod");
+ UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
AuthenticationManager am = mock(AuthenticationManager.class);
when(am.authenticate(any(Authentication.class))).thenThrow(new BadCredentialsException(""));
filter.setAuthenticationManager(am);
@@ -127,7 +127,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
// Check username has still been set
assertEquals("rod", request.getSession().getAttribute(
- AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
+ UsernamePasswordAuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
}
/**
@@ -137,7 +137,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
public void noSessionIsCreatedIfAllowSessionCreationIsFalse() throws Exception {
MockHttpServletRequest request = new MockHttpServletRequest();
- AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
+ UsernamePasswordAuthenticationProcessingFilter filter = new UsernamePasswordAuthenticationProcessingFilter();
filter.setAllowSessionCreation(false);
filter.setAuthenticationManager(createAuthenticationManager());
diff --git a/web/src/test/java/org/springframework/security/web/authentication/DefaultLoginPageGeneratingFilterTests.java b/web/src/test/java/org/springframework/security/web/authentication/DefaultLoginPageGeneratingFilterTests.java
index 9fbb86a04a..a2feedc785 100644
--- a/web/src/test/java/org/springframework/security/web/authentication/DefaultLoginPageGeneratingFilterTests.java
+++ b/web/src/test/java/org/springframework/security/web/authentication/DefaultLoginPageGeneratingFilterTests.java
@@ -30,7 +30,7 @@ public class DefaultLoginPageGeneratingFilterTests {
@Test
public void generatingPageWithAuthenticationProcessingFilterOnlyIsSuccessFul() throws Exception {
- DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new AuthenticationProcessingFilter());
+ DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new UsernamePasswordAuthenticationProcessingFilter());
filter.doFilter(new MockHttpServletRequest("GET", "/spring_security_login"), new MockHttpServletResponse(), chain);
filter.doFilter(new MockHttpServletRequest("GET", "/spring_security_login;pathparam=unused"), new MockHttpServletResponse(), chain);
}
@@ -43,7 +43,7 @@ public class DefaultLoginPageGeneratingFilterTests {
}
// Fake OpenID filter (since it's not in this module
- private static class MockProcessingFilter extends AbstractProcessingFilter {
+ private static class MockProcessingFilter extends AbstractAuthenticationProcessingFilter {
protected MockProcessingFilter() {
super("/someurl");
}
@@ -65,14 +65,14 @@ public class DefaultLoginPageGeneratingFilterTests {
/* SEC-1111 */
@Test
public void handlesNonIso8859CharsInErrorMessage() throws Exception {
- DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new AuthenticationProcessingFilter());
+ DefaultLoginPageGeneratingFilter filter = new DefaultLoginPageGeneratingFilter(new UsernamePasswordAuthenticationProcessingFilter());
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/spring_security_login");
request.addParameter("login_error", "true");
MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
String message = messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials", Locale.KOREA);
System.out.println("Message: " + message);
- request.getSession().setAttribute(AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, new BadCredentialsException(message));
+ request.getSession().setAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, new BadCredentialsException(message));
filter.doFilter(request, new MockHttpServletResponse(), chain);
}
diff --git a/web/src/test/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPointTests.java b/web/src/test/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPointTests.java
index 1de29fb05b..ab4f56ec9c 100755
--- a/web/src/test/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPointTests.java
+++ b/web/src/test/java/org/springframework/security/web/authentication/preauth/PreAuthenticatedProcessingFilterEntryPointTests.java
@@ -1,7 +1,7 @@
package org.springframework.security.web.authentication.preauth;
import org.springframework.security.authentication.AuthenticationCredentialsNotFoundException;
-import org.springframework.security.web.authentication.preauth.PreAuthenticatedProcessingFilterEntryPoint;
+import org.springframework.security.web.authentication.Http403ForbiddenEntryPoint;
import java.io.IOException;
@@ -21,7 +21,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
public class PreAuthenticatedProcessingFilterEntryPointTests extends TestCase {
public void testGetSetOrder() {
- PreAuthenticatedProcessingFilterEntryPoint fep = new PreAuthenticatedProcessingFilterEntryPoint();
+ Http403ForbiddenEntryPoint fep = new Http403ForbiddenEntryPoint();
fep.setOrder(333);
assertEquals(fep.getOrder(), 333);
}
@@ -29,7 +29,7 @@ public class PreAuthenticatedProcessingFilterEntryPointTests extends TestCase {
public void testCommence() {
MockHttpServletRequest req = new MockHttpServletRequest();
MockHttpServletResponse resp = new MockHttpServletResponse();
- PreAuthenticatedProcessingFilterEntryPoint fep = new PreAuthenticatedProcessingFilterEntryPoint();
+ Http403ForbiddenEntryPoint fep = new Http403ForbiddenEntryPoint();
try {
fep.commence(req,resp,new AuthenticationCredentialsNotFoundException("test"));
assertEquals("Incorrect status",resp.getStatus(),HttpServletResponse.SC_FORBIDDEN);
getRemoteUser()
or getUserPrincipal()
methods of the
@@ -75,8 +75,8 @@ import org.springframework.web.portlet.ModelAndView;
* details
property of the
Authentication
object that is sent
* as a request to the AuthenticationManager
.
*
- * @see org.springframework.security.web.authentication.AbstractProcessingFilter
- * @see org.springframework.security.web.authentication.AuthenticationProcessingFilter
+ * @see org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter
+ * @see org.springframework.security.web.authentication.UsernamePasswordAuthenticationProcessingFilter
* @author John A. Lewis
* @since 2.0
* @version $Id$
@@ -209,7 +209,7 @@ public class PortletProcessingInterceptor implements HandlerInterceptor, Initial
}
ctx.setAuthentication(null);
request.getPortletSession().setAttribute(
- AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY,
+ AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY,
failed, PortletSession.APPLICATION_SCOPE);
onUnsuccessfulAuthentication(request, response, failed);
}
diff --git a/portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java b/portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java
index 0fac061557..486eadaf22 100644
--- a/portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java
+++ b/portlet/src/test/java/org/springframework/security/portlet/PortletProcessingInterceptorTests.java
@@ -31,7 +31,7 @@ import org.springframework.mock.web.portlet.MockActionRequest;
import org.springframework.mock.web.portlet.MockActionResponse;
import org.springframework.mock.web.portlet.MockRenderRequest;
import org.springframework.mock.web.portlet.MockRenderResponse;
-import org.springframework.security.web.authentication.AbstractProcessingFilter;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
@@ -140,7 +140,7 @@ public class PortletProcessingInterceptorTests {
// Verify that proper exception was thrown
assertTrue(request.getPortletSession().getAttribute(
- AbstractProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY,
+ AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY,
PortletSession.APPLICATION_SCOPE)
instanceof BadCredentialsException);
}
diff --git a/samples/cas/client/src/main/webapp/casfailed.jsp b/samples/cas/client/src/main/webapp/casfailed.jsp
index e9fcbdb452..a1ff6b8114 100644
--- a/samples/cas/client/src/main/webapp/casfailed.jsp
+++ b/samples/cas/client/src/main/webapp/casfailed.jsp
@@ -1,5 +1,5 @@
<%@ page import="org.springframework.security.core.AuthenticationException" %>
-<%@ page import="org.springframework.security.web.authentication.AbstractProcessingFilter" %>
+<%@ page import="org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter" %>
diff --git a/samples/portlet/src/main/java/org/springframework/web/portlet/sample/SecurityContextPortlet.java b/samples/portlet/src/main/java/org/springframework/web/portlet/sample/SecurityContextPortlet.java
index 6062e76460..91b1af1513 100644
--- a/samples/portlet/src/main/java/org/springframework/web/portlet/sample/SecurityContextPortlet.java
+++ b/samples/portlet/src/main/java/org/springframework/web/portlet/sample/SecurityContextPortlet.java
@@ -11,7 +11,7 @@ import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.authentication.AbstractProcessingFilter;
+import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
/**
@@ -32,7 +32,7 @@ public class SecurityContextPortlet extends GenericPortlet {
out.println("ExceptionTranslationFilter
will populate the HttpSession
attribute named
- * AbstractProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY
with the requested target URL before
+ * AbstractAuthenticationProcessingFilter.SPRING_SECURITY_SAVED_REQUEST_KEY
with the requested target URL before
* calling this method.
* ServletResponse
as necessary to
diff --git a/web/src/main/java/org/springframework/security/web/access/ExceptionTranslationFilter.java b/web/src/main/java/org/springframework/security/web/access/ExceptionTranslationFilter.java
index b3d1b1f700..0703c6c8b3 100644
--- a/web/src/main/java/org/springframework/security/web/access/ExceptionTranslationFilter.java
+++ b/web/src/main/java/org/springframework/security/web/access/ExceptionTranslationFilter.java
@@ -206,7 +206,7 @@ public class ExceptionTranslationFilter extends SpringSecurityFilter implements
SavedRequest savedRequest = new SavedRequest(request, portResolver);
if (createSessionAllowed || request.getSession(false) != null) {
- // Store the HTTP request itself. Used by AbstractProcessingFilter
+ // Store the HTTP request itself. Used by AbstractAuthenticationProcessingFilter
// for redirection after successful authentication (SEC-29)
request.getSession().setAttribute(SavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest);
logger.debug("SavedRequest added to Session: " + savedRequest);
diff --git a/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java
new file mode 100644
index 0000000000..02dd4f3df3
--- /dev/null
+++ b/web/src/main/java/org/springframework/security/web/authentication/AbstractAuthenticationProcessingFilter.java
@@ -0,0 +1,439 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed 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.springframework.security.web.authentication;
+
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.context.ApplicationEventPublisherAware;
+import org.springframework.context.MessageSource;
+import org.springframework.context.MessageSourceAware;
+import org.springframework.context.support.MessageSourceAccessor;
+import org.springframework.security.authentication.AuthenticationDetailsSource;
+import org.springframework.security.authentication.AuthenticationManager;
+import org.springframework.security.authentication.concurrent.SessionRegistry;
+import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
+import org.springframework.security.core.Authentication;
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.core.SpringSecurityMessageSource;
+import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.security.web.SpringSecurityFilter;
+import org.springframework.security.web.session.SessionUtils;
+import org.springframework.security.web.util.UrlUtils;
+import org.springframework.util.Assert;
+
+/**
+ * Abstract processor of browser-based HTTP-based authentication requests.
+ *
+ * Authentication Process
+ *
+ * The filter requires that you set the authenticationManager property. An AuthenticationManager is
+ * required to process the authentication request tokens created by implementing classes.
+ * Authentication Success
+ *
+ * If authentication is successful, the resulting {@link Authentication} object will be placed into the
+ * SecurityContext
for the current thread, which is guaranteed to have already been created by an earlier
+ * filter. The configured {@link #setAuthenticationSuccessHandler(AuthenticationSuccessHandler) AuthenticationSuccessHandler} will
+ * then be called to take the redirect to the appropriate destination after a successful login. The default behaviour
+ * is implemented in a {@link SavedRequestAwareAuthenticationSuccessHandler} which will make use of any
+ * SavedRequest set by the ExceptionTranslationFilter and redirect the user to the URL contained
+ * therein. Otherwise it will redirect to the webapp root "/". You can customize this behaviour by injecting a
+ * differently configured instance of this class, or by using a different implementation.
+ * Authentication Failure
+ *
+ * If authentication fails, the resulting AuthenticationException will be placed into the HttpSession
+ * with the attribute defined by {@link #SPRING_SECURITY_LAST_EXCEPTION_KEY}. It will then delegate to the configured
+ * {@link AuthenticationFailureHandler} to allow the failure information to be conveyed to the client.
+ * The default implementation is {@link SimpleUrlAuthenticationFailureHandler}, which sends a 401 error code to the
+ * client. It may also be configured with a failure URL as an alternative. Again you can inject whatever
+ * behaviour you require here.
+ *
+ * Event Publication
+ *
+ * If authentication is successful, an
+ * {@link org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
+ * InteractiveAuthenticationSuccessEvent} will be published via the application context. No events will be published if
+ * authentication was unsuccessful, because this would generally be recorded via an
+ * AuthenticationManager-specific application event.
+ * /j_spring_security_check
)
+ */
+ private String filterProcessesUrl;
+
+ private boolean continueChainBeforeSuccessfulAuthentication = false;
+
+ /**
+ * Tells if we on successful authentication should invalidate the
+ * current session. This is a common guard against session fixation attacks.
+ * Defaults to false
.
+ */
+ private boolean invalidateSessionOnSuccessfulAuthentication = false;
+
+ /**
+ * If {@link #invalidateSessionOnSuccessfulAuthentication} is true, this
+ * flag indicates that the session attributes of the session to be invalidated
+ * are to be migrated to the new session. Defaults to true
since
+ * nothing will happen unless {@link #invalidateSessionOnSuccessfulAuthentication}
+ * is true.
+ */
+ private boolean migrateInvalidatedSessionAttributes = true;
+
+ private boolean allowSessionCreation = true;
+
+ private SessionRegistry sessionRegistry;
+
+ private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
+ private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
+
+ //~ Constructors ===================================================================================================
+
+ /**
+ * @param defaultFilterProcessesUrl the default value for filterProcessesUrl.
+ */
+ protected AbstractAuthenticationProcessingFilter(String defaultFilterProcessesUrl) {
+ this.filterProcessesUrl = defaultFilterProcessesUrl;
+ }
+
+ //~ Methods ========================================================================================================
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
+ Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL");
+ Assert.notNull(authenticationManager, "authenticationManager must be specified");
+
+ if (rememberMeServices == null) {
+ rememberMeServices = new NullRememberMeServices();
+ }
+ }
+
+ /**
+ * Invokes the {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse) requiresAuthentication}
+ * method to determine whether the request is for authentication and should be handled by this filter.
+ * If it is an authentication request, the
+ * {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse) attemptAuthentication} will be invoked
+ * to perform the authentication. There are then three possible outcomes:
+ *
+ *
+ */
+ public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+
+ if (!requiresAuthentication(request, response)) {
+ chain.doFilter(request, response);
+
+ return;
+ }
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Request is to process authentication");
+ }
+
+ Authentication authResult;
+
+ try {
+ authResult = attemptAuthentication(request, response);
+ if (authResult == null) {
+ // return immediately as subclass has indicated that it hasn't completed authentication
+ return;
+ }
+ }
+ catch (AuthenticationException failed) {
+ // Authentication failed
+ unsuccessfulAuthentication(request, response, failed);
+
+ return;
+ }
+
+ // Authentication success
+ if (continueChainBeforeSuccessfulAuthentication) {
+ chain.doFilter(request, response);
+ }
+
+ successfulAuthentication(request, response, authResult);
+ }
+
+ /**
+ * Indicates whether this filter should attempt to process a login request for the current invocation.
+ * filterProcessesUrl
property.
+ * true
if the filter should attempt authentication, false
otherwise.
+ */
+ protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
+ String uri = request.getRequestURI();
+ int pathParamIndex = uri.indexOf(';');
+
+ if (pathParamIndex > 0) {
+ // strip everything after the first semi-colon
+ uri = uri.substring(0, pathParamIndex);
+ }
+
+ if ("".equals(request.getContextPath())) {
+ return uri.endsWith(filterProcessesUrl);
+ }
+
+ return uri.endsWith(request.getContextPath() + filterProcessesUrl);
+ }
+
+ /**
+ * Performs actual authentication.
+ *
+ *
+ *
+ * @param request from which to extract parameters and perform the authentication
+ * @param response the response, which may be needed if the implementation has to do a redirect as part of a
+ * multi-stage authentication process (such as OpenID).
+ *
+ * @return the authenticated user token, or null if authentication is incomplete.
+ *
+ * @throws AuthenticationException if authentication fails.
+ */
+ public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
+ throws AuthenticationException, IOException, ServletException;
+
+ /**
+ * Default behaviour for successful authentication.
+ *
+ *
+ *
+ * @param authResult the object returned from the attemptAuthentication method.
+ */
+ protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
+ Authentication authResult) throws IOException, ServletException {
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
+ }
+
+ SecurityContextHolder.getContext().setAuthentication(authResult);
+
+ if (invalidateSessionOnSuccessfulAuthentication) {
+ SessionUtils.startNewSessionIfRequired(request, migrateInvalidatedSessionAttributes, sessionRegistry);
+ }
+
+ rememberMeServices.loginSuccess(request, response, authResult);
+
+ // Fire event
+ if (this.eventPublisher != null) {
+ eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
+ }
+
+ successHandler.onAuthenticationSuccess(request, response, authResult);
+ }
+
+ /**
+ * Default behaviour for unsuccessful authentication.
+ *
+ *
+ */
+ protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
+ AuthenticationException failed) throws IOException, ServletException {
+ SecurityContextHolder.clearContext();
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Authentication request failed: " + failed.toString());
+ logger.debug("Updated SecurityContextHolder to contain null Authentication");
+ logger.debug("Delegating to authentication failure handler" + failureHandler);
+ }
+
+ try {
+ HttpSession session = request.getSession(false);
+
+ if (session != null || allowSessionCreation) {
+ request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
+ }
+ }
+ catch (Exception ignored) {
+ }
+
+ rememberMeServices.loginFail(request, response);
+
+ failureHandler.onAuthenticationFailure(request, response, failed);
+ }
+
+ protected AuthenticationManager getAuthenticationManager() {
+ return authenticationManager;
+ }
+
+ public void setAuthenticationManager(AuthenticationManager authenticationManager) {
+ this.authenticationManager = authenticationManager;
+ }
+
+ public String getFilterProcessesUrl() {
+ return filterProcessesUrl;
+ }
+
+ public void setFilterProcessesUrl(String filterProcessesUrl) {
+ this.filterProcessesUrl = filterProcessesUrl;
+ }
+
+ public RememberMeServices getRememberMeServices() {
+ return rememberMeServices;
+ }
+
+ public void setRememberMeServices(RememberMeServices rememberMeServices) {
+ this.rememberMeServices = rememberMeServices;
+ }
+
+ /**
+ * Indicates if the filter chain should be continued prior to delegation to
+ * {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse,
+ * Authentication)}, which may be useful in certain environment (such as
+ * Tapestry applications). Defaults to false
.
+ */
+ public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
+ this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
+ }
+
+ public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
+ this.eventPublisher = eventPublisher;
+ }
+
+ public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
+ Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
+ this.authenticationDetailsSource = authenticationDetailsSource;
+ }
+
+ public void setMessageSource(MessageSource messageSource) {
+ this.messages = new MessageSourceAccessor(messageSource);
+ }
+
+ public void setInvalidateSessionOnSuccessfulAuthentication(boolean invalidateSessionOnSuccessfulAuthentication) {
+ this.invalidateSessionOnSuccessfulAuthentication = invalidateSessionOnSuccessfulAuthentication;
+ }
+
+ public void setMigrateInvalidatedSessionAttributes(boolean migrateInvalidatedSessionAttributes) {
+ this.migrateInvalidatedSessionAttributes = migrateInvalidatedSessionAttributes;
+ }
+
+ public AuthenticationDetailsSource getAuthenticationDetailsSource() {
+ // Required due to SEC-310
+ return authenticationDetailsSource;
+ }
+
+ protected boolean getAllowSessionCreation() {
+ return allowSessionCreation;
+ }
+
+ public void setAllowSessionCreation(boolean allowSessionCreation) {
+ this.allowSessionCreation = allowSessionCreation;
+ }
+
+ /**
+ * The session registry needs to be set if session fixation attack protection is in use (and concurrent
+ * session control is enabled).
+ */
+ public void setSessionRegistry(SessionRegistry sessionRegistry) {
+ this.sessionRegistry = sessionRegistry;
+ }
+
+ /**
+ * Sets the strategy used to handle a successful authentication.
+ * By default a {@link SavedRequestAwareAuthenticationSuccessHandler} is used.
+ */
+ public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
+ Assert.notNull(successHandler, "successHandler cannot be null");
+ this.successHandler = successHandler;
+ }
+
+ public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
+ Assert.notNull(failureHandler, "failureHandler cannot be null");
+ this.failureHandler = failureHandler;
+ }
+}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/AbstractProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/AbstractProcessingFilter.java
index 05ad766d04..4bbfd58dee 100644
--- a/web/src/main/java/org/springframework/security/web/authentication/AbstractProcessingFilter.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/AbstractProcessingFilter.java
@@ -1,439 +1,18 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed 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.springframework.security.web.authentication;
-import java.io.IOException;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.context.ApplicationEventPublisher;
-import org.springframework.context.ApplicationEventPublisherAware;
-import org.springframework.context.MessageSource;
-import org.springframework.context.MessageSourceAware;
-import org.springframework.context.support.MessageSourceAccessor;
-import org.springframework.security.authentication.AuthenticationDetailsSource;
-import org.springframework.security.authentication.AuthenticationManager;
-import org.springframework.security.authentication.concurrent.SessionRegistry;
-import org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-import org.springframework.security.core.SpringSecurityMessageSource;
-import org.springframework.security.core.context.SecurityContextHolder;
-import org.springframework.security.web.SpringSecurityFilter;
-import org.springframework.security.web.session.SessionUtils;
-import org.springframework.security.web.util.UrlUtils;
-import org.springframework.util.Assert;
-
/**
- * Abstract processor of browser-based HTTP-based authentication requests.
- *
- * Authentication Process
- *
- * The filter requires that you set the authenticationManager property. An AuthenticationManager is
- * required to process the authentication request tokens created by implementing classes.
+ * Renamed class, retained for backwards compatibility.
* Authentication Success
- *
- * If authentication is successful, the resulting {@link Authentication} object will be placed into the
- * SecurityContext
for the current thread, which is guaranteed to have already been created by an earlier
- * filter. The configured {@link #setAuthenticationSuccessHandler(AuthenticationSuccessHandler) AuthenticationSuccessHandler} will
- * then be called to take the redirect to the appropriate destination after a successful login. The default behaviour
- * is implemented in a {@link SavedRequestAwareAuthenticationSuccessHandler} which will make use of any
- * SavedRequest set by the ExceptionTranslationFilter and redirect the user to the URL contained
- * therein. Otherwise it will redirect to the webapp root "/". You can customize this behaviour by injecting a
- * differently configured instance of this class, or by using a different implementation.
- * Authentication Failure
- *
- * If authentication fails, the resulting AuthenticationException will be placed into the HttpSession
- * with the attribute defined by {@link #SPRING_SECURITY_LAST_EXCEPTION_KEY}. It will then delegate to the configured
- * {@link AuthenticationFailureHandler} to allow the failure information to be conveyed to the client.
- * The default implementation is {@link SimpleUrlAuthenticationFailureHandler}, which sends a 401 error code to the
- * client. It may also be configured with a failure URL as an alternative. Again you can inject whatever
- * behaviour you require here.
- *
- * Event Publication
- *
- * If authentication is successful, an
- * {@link org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent
- * InteractiveAuthenticationSuccessEvent} will be published via the application context. No events will be published if
- * authentication was unsuccessful, because this would generally be recorded via an
- * AuthenticationManager-specific application event.
- * /j_spring_security_check
)
- */
- private String filterProcessesUrl;
-
- private boolean continueChainBeforeSuccessfulAuthentication = false;
-
- /**
- * Tells if we on successful authentication should invalidate the
- * current session. This is a common guard against session fixation attacks.
- * Defaults to false
.
- */
- private boolean invalidateSessionOnSuccessfulAuthentication = false;
-
- /**
- * If {@link #invalidateSessionOnSuccessfulAuthentication} is true, this
- * flag indicates that the session attributes of the session to be invalidated
- * are to be migrated to the new session. Defaults to true
since
- * nothing will happen unless {@link #invalidateSessionOnSuccessfulAuthentication}
- * is true.
- */
- private boolean migrateInvalidatedSessionAttributes = true;
-
- private boolean allowSessionCreation = true;
-
- private SessionRegistry sessionRegistry;
-
- private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
- private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
-
- //~ Constructors ===================================================================================================
-
- /**
- * @param defaultFilterProcessesUrl the default value for filterProcessesUrl.
- */
protected AbstractProcessingFilter(String defaultFilterProcessesUrl) {
- this.filterProcessesUrl = defaultFilterProcessesUrl;
- }
-
- //~ Methods ========================================================================================================
-
- public void afterPropertiesSet() throws Exception {
- Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
- Assert.isTrue(UrlUtils.isValidRedirectUrl(filterProcessesUrl), filterProcessesUrl + " isn't a valid redirect URL");
- Assert.notNull(authenticationManager, "authenticationManager must be specified");
-
- if (rememberMeServices == null) {
- rememberMeServices = new NullRememberMeServices();
- }
- }
-
- /**
- * Invokes the {@link #requiresAuthentication(HttpServletRequest, HttpServletResponse) requiresAuthentication}
- * method to determine whether the request is for authentication and should be handled by this filter.
- * If it is an authentication request, the
- * {@link #attemptAuthentication(HttpServletRequest, HttpServletResponse) attemptAuthentication} will be invoked
- * to perform the authentication. There are then three possible outcomes:
- *
- *
- */
- public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
- throws IOException, ServletException {
-
- if (!requiresAuthentication(request, response)) {
- chain.doFilter(request, response);
-
- return;
- }
-
- if (logger.isDebugEnabled()) {
- logger.debug("Request is to process authentication");
- }
-
- Authentication authResult;
-
- try {
- authResult = attemptAuthentication(request, response);
- if (authResult == null) {
- // return immediately as subclass has indicated that it hasn't completed authentication
- return;
- }
- }
- catch (AuthenticationException failed) {
- // Authentication failed
- unsuccessfulAuthentication(request, response, failed);
-
- return;
- }
-
- // Authentication success
- if (continueChainBeforeSuccessfulAuthentication) {
- chain.doFilter(request, response);
- }
-
- successfulAuthentication(request, response, authResult);
- }
-
- /**
- * Indicates whether this filter should attempt to process a login request for the current invocation.
- * filterProcessesUrl
property.
- * true
if the filter should attempt authentication, false
otherwise.
- */
- protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
- String uri = request.getRequestURI();
- int pathParamIndex = uri.indexOf(';');
-
- if (pathParamIndex > 0) {
- // strip everything after the first semi-colon
- uri = uri.substring(0, pathParamIndex);
- }
-
- if ("".equals(request.getContextPath())) {
- return uri.endsWith(filterProcessesUrl);
- }
-
- return uri.endsWith(request.getContextPath() + filterProcessesUrl);
- }
-
- /**
- * Performs actual authentication.
- *
- *
- *
- * @param request from which to extract parameters and perform the authentication
- * @param response the response, which may be needed if the implementation has to do a redirect as part of a
- * multi-stage authentication process (such as OpenID).
- *
- * @return the authenticated user token, or null if authentication is incomplete.
- *
- * @throws AuthenticationException if authentication fails.
- */
- public abstract Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
- throws AuthenticationException, IOException, ServletException;
-
- /**
- * Default behaviour for successful authentication.
- *
- *
- *
- * @param authResult the object returned from the attemptAuthentication method.
- */
- protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
- Authentication authResult) throws IOException, ServletException {
-
- if (logger.isDebugEnabled()) {
- logger.debug("Authentication success. Updating SecurityContextHolder to contain: " + authResult);
- }
-
- SecurityContextHolder.getContext().setAuthentication(authResult);
-
- if (invalidateSessionOnSuccessfulAuthentication) {
- SessionUtils.startNewSessionIfRequired(request, migrateInvalidatedSessionAttributes, sessionRegistry);
- }
-
- rememberMeServices.loginSuccess(request, response, authResult);
-
- // Fire event
- if (this.eventPublisher != null) {
- eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
- }
-
- successHandler.onAuthenticationSuccess(request, response, authResult);
- }
-
- /**
- * Default behaviour for unsuccessful authentication.
- *
- *
- */
- protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException failed) throws IOException, ServletException {
- SecurityContextHolder.clearContext();
-
- if (logger.isDebugEnabled()) {
- logger.debug("Authentication request failed: " + failed.toString());
- logger.debug("Updated SecurityContextHolder to contain null Authentication");
- logger.debug("Delegating to authentication failure handler" + failureHandler);
- }
-
- try {
- HttpSession session = request.getSession(false);
-
- if (session != null || allowSessionCreation) {
- request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
- }
- }
- catch (Exception ignored) {
- }
-
- rememberMeServices.loginFail(request, response);
-
- failureHandler.onAuthenticationFailure(request, response, failed);
- }
-
- protected AuthenticationManager getAuthenticationManager() {
- return authenticationManager;
- }
-
- public void setAuthenticationManager(AuthenticationManager authenticationManager) {
- this.authenticationManager = authenticationManager;
- }
-
- public String getFilterProcessesUrl() {
- return filterProcessesUrl;
- }
-
- public void setFilterProcessesUrl(String filterProcessesUrl) {
- this.filterProcessesUrl = filterProcessesUrl;
- }
-
- public RememberMeServices getRememberMeServices() {
- return rememberMeServices;
- }
-
- public void setRememberMeServices(RememberMeServices rememberMeServices) {
- this.rememberMeServices = rememberMeServices;
- }
-
- /**
- * Indicates if the filter chain should be continued prior to delegation to
- * {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse,
- * Authentication)}, which may be useful in certain environment (such as
- * Tapestry applications). Defaults to false
.
- */
- public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
- this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
- }
-
- public void setApplicationEventPublisher(ApplicationEventPublisher eventPublisher) {
- this.eventPublisher = eventPublisher;
- }
-
- public void setAuthenticationDetailsSource(AuthenticationDetailsSource authenticationDetailsSource) {
- Assert.notNull(authenticationDetailsSource, "AuthenticationDetailsSource required");
- this.authenticationDetailsSource = authenticationDetailsSource;
- }
-
- public void setMessageSource(MessageSource messageSource) {
- this.messages = new MessageSourceAccessor(messageSource);
- }
-
- public void setInvalidateSessionOnSuccessfulAuthentication(boolean invalidateSessionOnSuccessfulAuthentication) {
- this.invalidateSessionOnSuccessfulAuthentication = invalidateSessionOnSuccessfulAuthentication;
- }
-
- public void setMigrateInvalidatedSessionAttributes(boolean migrateInvalidatedSessionAttributes) {
- this.migrateInvalidatedSessionAttributes = migrateInvalidatedSessionAttributes;
- }
-
- public AuthenticationDetailsSource getAuthenticationDetailsSource() {
- // Required due to SEC-310
- return authenticationDetailsSource;
- }
-
- protected boolean getAllowSessionCreation() {
- return allowSessionCreation;
- }
-
- public void setAllowSessionCreation(boolean allowSessionCreation) {
- this.allowSessionCreation = allowSessionCreation;
- }
-
- /**
- * The session registry needs to be set if session fixation attack protection is in use (and concurrent
- * session control is enabled).
- */
- public void setSessionRegistry(SessionRegistry sessionRegistry) {
- this.sessionRegistry = sessionRegistry;
- }
-
- /**
- * Sets the strategy used to handle a successful authentication.
- * By default a {@link SavedRequestAwareAuthenticationSuccessHandler} is used.
- */
- public void setAuthenticationSuccessHandler(AuthenticationSuccessHandler successHandler) {
- Assert.notNull(successHandler, "successHandler cannot be null");
- this.successHandler = successHandler;
- }
-
- public void setAuthenticationFailureHandler(AuthenticationFailureHandler failureHandler) {
- Assert.notNull(failureHandler, "failureHandler cannot be null");
- this.failureHandler = failureHandler;
+ super(defaultFilterProcessesUrl);
}
}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilter.java b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilter.java
index 107cf553ca..9caf795668 100644
--- a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilter.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationProcessingFilter.java
@@ -1,182 +1,15 @@
-/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
- *
- * Licensed 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.springframework.security.web.authentication;
-
-import org.springframework.security.authentication.AuthenticationServiceException;
-import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
-import org.springframework.security.core.Authentication;
-import org.springframework.security.core.AuthenticationException;
-
-import org.springframework.security.web.FilterChainOrder;
-import org.springframework.security.web.util.TextEscapeUtils;
-import org.springframework.util.Assert;
-
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
-
-
/**
- * Processes an authentication form.
+ * Renamed class, retained for backwards compatibility.
* AuthenticationDao
will need to generate the expected password in a corresponding manner.Authentication
request token to the
- * AuthenticationManager
- */
- protected String obtainPassword(HttpServletRequest request) {
- return request.getParameter(passwordParameter);
- }
-
- /**
- * Enables subclasses to override the composition of the username, such as by including additional values
- * and a separator.
- *
- * @param request so that request attributes can be retrieved
- *
- * @return the username that will be presented in the Authentication
request token to the
- * AuthenticationManager
- */
- protected String obtainUsername(HttpServletRequest request) {
- return request.getParameter(usernameParameter);
- }
-
- /**
- * Provided so that subclasses may configure what is put into the authentication request's details
- * property.
- *
- * @param request that an authentication request is being created for
- * @param authRequest the authentication request object that should have its details set
- */
- protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
- authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
- }
-
- /**
- * Sets the parameter name which will be used to obtain the username from the login request.
- *
- * @param usernameParameter the parameter name. Defaults to "j_username".
- */
- public void setUsernameParameter(String usernameParameter) {
- Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
- this.usernameParameter = usernameParameter;
- }
-
- /**
- * Sets the parameter name which will be used to obtain the password from the login request..
- *
- * @param passwordParameter the parameter name. Defaults to "j_password".
- */
- public void setPasswordParameter(String passwordParameter) {
- Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
- this.passwordParameter = passwordParameter;
- }
-
- /**
- * Defines whether only HTTP POST requests will be allowed by this filter.
- * If set to true, and an authentication request is received which is not a POST request, an exception will
- * be raised immediately and authentication will not be attempted. The unsuccessfulAuthentication() method
- * will be called as if handling a failed authentication.
- * HTTPS
,
- * even if the original intercepted request for a resource used the
- * HTTP
protocol. When this happens, after a successful login
- * (via HTTPS), the original resource will still be accessed as HTTP, via the
- * original request URL. For the forced HTTPS feature to work, the {@link
- * PortMapper} is consulted to determine the HTTP:HTTPS pairs.
+ * See {@link LoginUrlAuthenticationEntryPoint}.
*
- * @author Ben Alex
- * @author colin sampaleanu
- * @author Omri Spector
+ * @author Luke Taylor
* @version $Id$
+ * @deprecated Use LoginUrlAuthenticationEntryPoint instead.
*/
-public class AuthenticationProcessingFilterEntryPoint implements AuthenticationEntryPoint, InitializingBean {
- //~ Static fields/initializers =====================================================================================
+public class AuthenticationProcessingFilterEntryPoint extends LoginUrlAuthenticationEntryPoint{
- private static final Log logger = LogFactory.getLog(AuthenticationProcessingFilterEntryPoint.class);
-
- //~ Instance fields ================================================================================================
-
- private PortMapper portMapper = new PortMapperImpl();
-
- private PortResolver portResolver = new PortResolverImpl();
-
- private String loginFormUrl;
-
- private boolean forceHttps = false;
-
- private boolean useForward = false;
-
- //~ Methods ========================================================================================================
-
- public void afterPropertiesSet() throws Exception {
- Assert.isTrue(StringUtils.hasText(loginFormUrl) && UrlUtils.isValidRedirectUrl(loginFormUrl),
- "loginFormUrl must be specified and must be a valid redirect URL");
- Assert.notNull(portMapper, "portMapper must be specified");
- Assert.notNull(portResolver, "portResolver must be specified");
- }
-
- /**
- * Allows subclasses to modify the login form URL that should be applicable for a given request.
- *
- * @param request the request
- * @param response the response
- * @param exception the exception
- * @return the URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()})
- */
- protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException exception) {
-
- return getLoginFormUrl();
- }
-
- /**
- * Performs the redirect (or forward) to the login form URL.
- */
- public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
- throws IOException, ServletException {
-
- HttpServletRequest httpRequest = (HttpServletRequest) request;
- HttpServletResponse httpResponse = (HttpServletResponse) response;
-
- String redirectUrl = null;
-
- if (useForward) {
-
- if (forceHttps && "http".equals(request.getScheme())) {
- redirectUrl = buildHttpsRedirectUrlForRequest(httpRequest);
- }
-
- if (redirectUrl == null) {
- String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException);
-
- if (logger.isDebugEnabled()) {
- logger.debug("Server side forward to: " + loginForm);
- }
-
- RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginForm);
-
- dispatcher.forward(request, response);
-
- return;
- }
- } else {
- // redirect to login page. Use https if forceHttps true
-
- redirectUrl = buildRedirectUrlToLoginPage(httpRequest, httpResponse, authException);
-
- }
-
- httpResponse.sendRedirect(httpResponse.encodeRedirectURL(redirectUrl));
- }
-
- protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
- AuthenticationException authException) {
-
- String loginForm = determineUrlToUseForThisRequest(request, response, authException);
- int serverPort = portResolver.getServerPort(request);
- String scheme = request.getScheme();
-
- RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
-
- urlBuilder.setScheme(scheme);
- urlBuilder.setServerName(request.getServerName());
- urlBuilder.setPort(serverPort);
- urlBuilder.setContextPath(request.getContextPath());
- urlBuilder.setPathInfo(loginForm);
-
- if (forceHttps && "http".equals(scheme)) {
- Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
-
- if (httpsPort != null) {
- // Overwrite scheme and port in the redirect URL
- urlBuilder.setScheme("https");
- urlBuilder.setPort(httpsPort.intValue());
- } else {
- logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
- }
- }
-
- return urlBuilder.getUrl();
- }
-
- /**
- * Builds a URL to redirect the supplied request to HTTPS.
- */
- protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
- throws IOException, ServletException {
-
- int serverPort = portResolver.getServerPort(request);
- Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
-
- if (httpsPort != null) {
- RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
- urlBuilder.setScheme("https");
- urlBuilder.setServerName(request.getServerName());
- urlBuilder.setPort(httpsPort.intValue());
- urlBuilder.setContextPath(request.getContextPath());
- urlBuilder.setServletPath(request.getServletPath());
- urlBuilder.setPathInfo(request.getPathInfo());
- urlBuilder.setQuery(request.getQueryString());
-
- return urlBuilder.getUrl();
- }
-
- // Fall through to server-side forward with warning message
- logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
-
- return null;
- }
-
- /**
- * Set to true to force login form access to be via https. If this value is true (the default is false),
- * and the incoming request for the protected resource which triggered the interceptor was not already
- * https
, then the client will first be redirected to an https URL, even if serverSideRedirect
- * is set to true.
- */
- public void setForceHttps(boolean forceHttps) {
- this.forceHttps = forceHttps;
- }
-
- protected boolean isForceHttps() {
- return forceHttps;
- }
-
- /**
- * The URL where the AuthenticationProcessingFilter
login
- * page can be found. Should be relative to the web-app context path, and
- * include a leading /
- */
- public void setLoginFormUrl(String loginFormUrl) {
- this.loginFormUrl = loginFormUrl;
- }
-
- public String getLoginFormUrl() {
- return loginFormUrl;
- }
-
- public void setPortMapper(PortMapper portMapper) {
- this.portMapper = portMapper;
- }
-
- protected PortMapper getPortMapper() {
- return portMapper;
- }
-
- public void setPortResolver(PortResolver portResolver) {
- this.portResolver = portResolver;
- }
-
- protected PortResolver getPortResolver() {
- return portResolver;
- }
-
- /**
- * Tells if we are to do a forward to the loginFormUrl
using the RequestDispatcher,
- * instead of a 302 redirect.
- *
- * @param useForward
- */
- public void setUseForward(boolean useForward) {
- this.useForward = useForward;
- }
-
- protected boolean isUseForward() {
- return useForward;
- }
}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationSuccessHandler.java b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationSuccessHandler.java
index 3735d6cbf5..754ac612ac 100644
--- a/web/src/main/java/org/springframework/security/web/authentication/AuthenticationSuccessHandler.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/AuthenticationSuccessHandler.java
@@ -14,7 +14,7 @@ import org.springframework.security.core.Authentication;
* Implementations can do whatever they want but typical behaviour would be to control the navigation to the
* subsequent destination (using a redirect or a forward). For example, after a user has logged in by submitting a
* login form, the application needs to decide where they should be redirected to afterwards
- * (see {@link AbstractProcessingFilter} and subclasses). Other logic may also be included if required.
+ * (see {@link AbstractAuthenticationProcessingFilter} and subclasses). Other logic may also be included if required.
*
* @author Luke Taylor
* @version $Id$
diff --git a/web/src/main/java/org/springframework/security/web/authentication/Http403ForbiddenEntryPoint.java b/web/src/main/java/org/springframework/security/web/authentication/Http403ForbiddenEntryPoint.java
new file mode 100755
index 0000000000..8e2351a75c
--- /dev/null
+++ b/web/src/main/java/org/springframework/security/web/authentication/Http403ForbiddenEntryPoint.java
@@ -0,0 +1,62 @@
+package org.springframework.security.web.authentication;
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+
+import java.io.IOException;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.springframework.core.Ordered;
+
+/**
+ * commence
method will always return an
+ * HttpServletResponse.SC_FORBIDDEN
(403 error).
+ *
+ * @see org.springframework.security.web.access.ExceptionTranslationFilter
+ *
+ * @author Luke Taylor
+ * @author Ruud Senden
+ * @since 2.0
+ */
+public class Http403ForbiddenEntryPoint implements AuthenticationEntryPoint, Ordered {
+ private static final Log logger = LogFactory.getLog(Http403ForbiddenEntryPoint.class);
+
+ private int order = Integer.MAX_VALUE;
+
+ /**
+ * Always returns a 403 error code to the client.
+ */
+ public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException arg2) throws IOException,
+ ServletException {
+ if (logger.isDebugEnabled()) {
+ logger.debug("Pre-authenticated entry point called. Rejecting access");
+ }
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied");
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setOrder(int i) {
+ order = i;
+ }
+
+}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.java b/web/src/main/java/org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.java
new file mode 100644
index 0000000000..35768f074a
--- /dev/null
+++ b/web/src/main/java/org/springframework/security/web/authentication/LoginUrlAuthenticationEntryPoint.java
@@ -0,0 +1,260 @@
+/* Copyright 2004, 2005, 2006 Acegi Technology Pty Limited
+ *
+ * Licensed 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.springframework.security.web.authentication;
+
+
+
+import org.springframework.security.core.AuthenticationException;
+import org.springframework.security.web.AuthenticationEntryPoint;
+import org.springframework.security.web.PortMapper;
+import org.springframework.security.web.PortMapperImpl;
+import org.springframework.security.web.PortResolver;
+import org.springframework.security.web.PortResolverImpl;
+import org.springframework.security.web.access.ExceptionTranslationFilter;
+import org.springframework.security.web.util.RedirectUrlBuilder;
+import org.springframework.security.web.util.UrlUtils;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import org.springframework.beans.factory.InitializingBean;
+
+import org.springframework.util.Assert;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Used by the {@link ExceptionTranslationFilter} to commence a form login
+ * authentication via the {@link UsernamePasswordAuthenticationProcessingFilter}. This object
+ * holds the location of the login form, relative to the web app context path,
+ * and is used to commence a redirect to that form.
+ * HTTPS
,
+ * even if the original intercepted request for a resource used the
+ * HTTP
protocol. When this happens, after a successful login
+ * (via HTTPS), the original resource will still be accessed as HTTP, via the
+ * original request URL. For the forced HTTPS feature to work, the {@link
+ * PortMapper} is consulted to determine the HTTP:HTTPS pairs.
+ *
+ * @author Ben Alex
+ * @author colin sampaleanu
+ * @author Omri Spector
+ * @author Luke Taylor
+ * @version $Id$
+ * @since 3.0
+ */
+public class LoginUrlAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean {
+ //~ Static fields/initializers =====================================================================================
+
+ private static final Log logger = LogFactory.getLog(LoginUrlAuthenticationEntryPoint.class);
+
+ //~ Instance fields ================================================================================================
+
+ private PortMapper portMapper = new PortMapperImpl();
+
+ private PortResolver portResolver = new PortResolverImpl();
+
+ private String loginFormUrl;
+
+ private boolean forceHttps = false;
+
+ private boolean useForward = false;
+
+ //~ Methods ========================================================================================================
+
+ public void afterPropertiesSet() throws Exception {
+ Assert.isTrue(StringUtils.hasText(loginFormUrl) && UrlUtils.isValidRedirectUrl(loginFormUrl),
+ "loginFormUrl must be specified and must be a valid redirect URL");
+ Assert.notNull(portMapper, "portMapper must be specified");
+ Assert.notNull(portResolver, "portResolver must be specified");
+ }
+
+ /**
+ * Allows subclasses to modify the login form URL that should be applicable for a given request.
+ *
+ * @param request the request
+ * @param response the response
+ * @param exception the exception
+ * @return the URL (cannot be null or empty; defaults to {@link #getLoginFormUrl()})
+ */
+ protected String determineUrlToUseForThisRequest(HttpServletRequest request, HttpServletResponse response,
+ AuthenticationException exception) {
+
+ return getLoginFormUrl();
+ }
+
+ /**
+ * Performs the redirect (or forward) to the login form URL.
+ */
+ public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException)
+ throws IOException, ServletException {
+
+ HttpServletRequest httpRequest = (HttpServletRequest) request;
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+
+ String redirectUrl = null;
+
+ if (useForward) {
+
+ if (forceHttps && "http".equals(request.getScheme())) {
+ redirectUrl = buildHttpsRedirectUrlForRequest(httpRequest);
+ }
+
+ if (redirectUrl == null) {
+ String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException);
+
+ if (logger.isDebugEnabled()) {
+ logger.debug("Server side forward to: " + loginForm);
+ }
+
+ RequestDispatcher dispatcher = httpRequest.getRequestDispatcher(loginForm);
+
+ dispatcher.forward(request, response);
+
+ return;
+ }
+ } else {
+ // redirect to login page. Use https if forceHttps true
+
+ redirectUrl = buildRedirectUrlToLoginPage(httpRequest, httpResponse, authException);
+
+ }
+
+ httpResponse.sendRedirect(httpResponse.encodeRedirectURL(redirectUrl));
+ }
+
+ protected String buildRedirectUrlToLoginPage(HttpServletRequest request, HttpServletResponse response,
+ AuthenticationException authException) {
+
+ String loginForm = determineUrlToUseForThisRequest(request, response, authException);
+ int serverPort = portResolver.getServerPort(request);
+ String scheme = request.getScheme();
+
+ RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
+
+ urlBuilder.setScheme(scheme);
+ urlBuilder.setServerName(request.getServerName());
+ urlBuilder.setPort(serverPort);
+ urlBuilder.setContextPath(request.getContextPath());
+ urlBuilder.setPathInfo(loginForm);
+
+ if (forceHttps && "http".equals(scheme)) {
+ Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
+
+ if (httpsPort != null) {
+ // Overwrite scheme and port in the redirect URL
+ urlBuilder.setScheme("https");
+ urlBuilder.setPort(httpsPort.intValue());
+ } else {
+ logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
+ }
+ }
+
+ return urlBuilder.getUrl();
+ }
+
+ /**
+ * Builds a URL to redirect the supplied request to HTTPS.
+ */
+ protected String buildHttpsRedirectUrlForRequest(HttpServletRequest request)
+ throws IOException, ServletException {
+
+ int serverPort = portResolver.getServerPort(request);
+ Integer httpsPort = portMapper.lookupHttpsPort(new Integer(serverPort));
+
+ if (httpsPort != null) {
+ RedirectUrlBuilder urlBuilder = new RedirectUrlBuilder();
+ urlBuilder.setScheme("https");
+ urlBuilder.setServerName(request.getServerName());
+ urlBuilder.setPort(httpsPort.intValue());
+ urlBuilder.setContextPath(request.getContextPath());
+ urlBuilder.setServletPath(request.getServletPath());
+ urlBuilder.setPathInfo(request.getPathInfo());
+ urlBuilder.setQuery(request.getQueryString());
+
+ return urlBuilder.getUrl();
+ }
+
+ // Fall through to server-side forward with warning message
+ logger.warn("Unable to redirect to HTTPS as no port mapping found for HTTP port " + serverPort);
+
+ return null;
+ }
+
+ /**
+ * Set to true to force login form access to be via https. If this value is true (the default is false),
+ * and the incoming request for the protected resource which triggered the interceptor was not already
+ * https
, then the client will first be redirected to an https URL, even if serverSideRedirect
+ * is set to true.
+ */
+ public void setForceHttps(boolean forceHttps) {
+ this.forceHttps = forceHttps;
+ }
+
+ protected boolean isForceHttps() {
+ return forceHttps;
+ }
+
+ /**
+ * The URL where the UsernamePasswordAuthenticationProcessingFilter
login
+ * page can be found. Should be relative to the web-app context path, and
+ * include a leading /
+ */
+ public void setLoginFormUrl(String loginFormUrl) {
+ this.loginFormUrl = loginFormUrl;
+ }
+
+ public String getLoginFormUrl() {
+ return loginFormUrl;
+ }
+
+ public void setPortMapper(PortMapper portMapper) {
+ this.portMapper = portMapper;
+ }
+
+ protected PortMapper getPortMapper() {
+ return portMapper;
+ }
+
+ public void setPortResolver(PortResolver portResolver) {
+ this.portResolver = portResolver;
+ }
+
+ protected PortResolver getPortResolver() {
+ return portResolver;
+ }
+
+ /**
+ * Tells if we are to do a forward to the loginFormUrl
using the RequestDispatcher,
+ * instead of a 302 redirect.
+ *
+ * @param useForward
+ */
+ public void setUseForward(boolean useForward) {
+ this.useForward = useForward;
+ }
+
+ protected boolean isUseForward() {
+ return useForward;
+ }
+}
diff --git a/web/src/main/java/org/springframework/security/web/authentication/RememberMeServices.java b/web/src/main/java/org/springframework/security/web/authentication/RememberMeServices.java
index 1a84b92026..1be37f6724 100644
--- a/web/src/main/java/org/springframework/security/web/authentication/RememberMeServices.java
+++ b/web/src/main/java/org/springframework/security/web/authentication/RememberMeServices.java
@@ -25,7 +25,7 @@ import org.springframework.security.core.Authentication;
* Implement by a class that is capable of providing a remember-me service.
*
* AuthenticationDao
will need to generate the expected password in a corresponding manner.Authentication
request token to the
+ * AuthenticationManager
+ */
+ protected String obtainPassword(HttpServletRequest request) {
+ return request.getParameter(passwordParameter);
+ }
+
+ /**
+ * Enables subclasses to override the composition of the username, such as by including additional values
+ * and a separator.
+ *
+ * @param request so that request attributes can be retrieved
+ *
+ * @return the username that will be presented in the Authentication
request token to the
+ * AuthenticationManager
+ */
+ protected String obtainUsername(HttpServletRequest request) {
+ return request.getParameter(usernameParameter);
+ }
+
+ /**
+ * Provided so that subclasses may configure what is put into the authentication request's details
+ * property.
+ *
+ * @param request that an authentication request is being created for
+ * @param authRequest the authentication request object that should have its details set
+ */
+ protected void setDetails(HttpServletRequest request, UsernamePasswordAuthenticationToken authRequest) {
+ authRequest.setDetails(authenticationDetailsSource.buildDetails(request));
+ }
+
+ /**
+ * Sets the parameter name which will be used to obtain the username from the login request.
+ *
+ * @param usernameParameter the parameter name. Defaults to "j_username".
+ */
+ public void setUsernameParameter(String usernameParameter) {
+ Assert.hasText(usernameParameter, "Username parameter must not be empty or null");
+ this.usernameParameter = usernameParameter;
+ }
+
+ /**
+ * Sets the parameter name which will be used to obtain the password from the login request..
+ *
+ * @param passwordParameter the parameter name. Defaults to "j_password".
+ */
+ public void setPasswordParameter(String passwordParameter) {
+ Assert.hasText(passwordParameter, "Password parameter must not be empty or null");
+ this.passwordParameter = passwordParameter;
+ }
+
+ /**
+ * Defines whether only HTTP POST requests will be allowed by this filter.
+ * If set to true, and an authentication request is received which is not a POST request, an exception will
+ * be raised immediately and authentication will not be attempted. The unsuccessfulAuthentication() method
+ * will be called as if handling a failed authentication.
+ * commence
method will always return an
- * HttpServletResponse.SC_FORBIDDEN
(403 error).
- * HttpServletRequest
.