SEC-1429: Move logic for saving of AuthenticationException into the SimpleUrlAuthenticationFailurehandler from AbstractAuthenticationProcessingFilter. It will also now use request scope if configured to do a forward instead of a redirect.

This commit is contained in:
Luke Taylor 2010-03-04 21:21:07 +00:00
parent 41e06152b3
commit 87cf27ab7c
18 changed files with 116 additions and 53 deletions

View File

@ -155,7 +155,7 @@ final class AuthenticationConfigBuilder {
if (formLoginElt != null || autoConfig) { if (formLoginElt != null || autoConfig) {
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_security_check", FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_security_check",
AUTHENTICATION_PROCESSING_FILTER_CLASS, requestCache, sessionStrategy); AUTHENTICATION_PROCESSING_FILTER_CLASS, requestCache, sessionStrategy, allowSessionCreation);
parser.parse(formLoginElt, pc); parser.parse(formLoginElt, pc);
formFilter = parser.getFilterBean(); formFilter = parser.getFilterBean();
@ -163,7 +163,7 @@ final class AuthenticationConfigBuilder {
} }
if (formFilter != null) { if (formFilter != null) {
formFilter.getPropertyValues().addPropertyValue("allowSessionCreation", new Boolean(allowSessionCreation)); formFilter.getPropertyValues().addPropertyValue("allowSessionCreation", allowSessionCreation);
formFilter.getPropertyValues().addPropertyValue("authenticationManager", authManager); formFilter.getPropertyValues().addPropertyValue("authenticationManager", authManager);
@ -179,7 +179,7 @@ final class AuthenticationConfigBuilder {
if (openIDLoginElt != null) { if (openIDLoginElt != null) {
FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_openid_security_check", FormLoginBeanDefinitionParser parser = new FormLoginBeanDefinitionParser("/j_spring_openid_security_check",
OPEN_ID_AUTHENTICATION_PROCESSING_FILTER_CLASS, requestCache, sessionStrategy); OPEN_ID_AUTHENTICATION_PROCESSING_FILTER_CLASS, requestCache, sessionStrategy, allowSessionCreation);
parser.parse(openIDLoginElt, pc); parser.parse(openIDLoginElt, pc);
openIDFilter = parser.getFilterBean(); openIDFilter = parser.getFilterBean();
@ -214,7 +214,7 @@ final class AuthenticationConfigBuilder {
} }
if (openIDFilter != null) { if (openIDFilter != null) {
openIDFilter.getPropertyValues().addPropertyValue("allowSessionCreation", new Boolean(allowSessionCreation)); openIDFilter.getPropertyValues().addPropertyValue("allowSessionCreation", allowSessionCreation);
openIDFilter.getPropertyValues().addPropertyValue("authenticationManager", authManager); openIDFilter.getPropertyValues().addPropertyValue("authenticationManager", authManager);
// Required by login page filter // Required by login page filter
openIDFilterId = pc.getReaderContext().generateBeanName(openIDFilter); openIDFilterId = pc.getReaderContext().generateBeanName(openIDFilter);
@ -540,7 +540,8 @@ final class AuthenticationConfigBuilder {
} }
void createUserServiceInjector() { void createUserServiceInjector() {
BeanDefinitionBuilder userServiceInjector = BeanDefinitionBuilder.rootBeanDefinition(UserDetailsServiceInjectionBeanPostProcessor.class); BeanDefinitionBuilder userServiceInjector =
BeanDefinitionBuilder.rootBeanDefinition(UserDetailsServiceInjectionBeanPostProcessor.class);
userServiceInjector.addConstructorArgValue(x509ProviderId); userServiceInjector.addConstructorArgValue(x509ProviderId);
userServiceInjector.addConstructorArgValue(rememberMeServicesId); userServiceInjector.addConstructorArgValue(rememberMeServicesId);
userServiceInjector.addConstructorArgValue(openIDProviderId); userServiceInjector.addConstructorArgValue(openIDProviderId);

View File

@ -31,7 +31,8 @@ public class FormLoginBeanDefinitionParser {
private static final String DEF_FORM_LOGIN_TARGET_URL = "/"; private static final String DEF_FORM_LOGIN_TARGET_URL = "/";
private static final String ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = "authentication-failure-url"; private static final String ATT_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = "authentication-failure-url";
private static final String DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL = DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL + "?" + DefaultLoginPageGeneratingFilter.ERROR_PARAMETER_NAME; private static final String DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL =
DefaultLoginPageGeneratingFilter.DEFAULT_LOGIN_PAGE_URL + "?" + DefaultLoginPageGeneratingFilter.ERROR_PARAMETER_NAME;
private static final String ATT_SUCCESS_HANDLER_REF = "authentication-success-handler-ref"; private static final String ATT_SUCCESS_HANDLER_REF = "authentication-success-handler-ref";
private static final String ATT_FAILURE_HANDLER_REF = "authentication-failure-handler-ref"; private static final String ATT_FAILURE_HANDLER_REF = "authentication-failure-handler-ref";
@ -40,17 +41,19 @@ public class FormLoginBeanDefinitionParser {
private final String filterClassName; private final String filterClassName;
private final BeanReference requestCache; private final BeanReference requestCache;
private final BeanReference sessionStrategy; private final BeanReference sessionStrategy;
private final boolean allowSessionCreation;
private RootBeanDefinition filterBean; private RootBeanDefinition filterBean;
private RootBeanDefinition entryPointBean; private RootBeanDefinition entryPointBean;
private String loginPage; private String loginPage;
FormLoginBeanDefinitionParser(String defaultLoginProcessingUrl, String filterClassName, FormLoginBeanDefinitionParser(String defaultLoginProcessingUrl, String filterClassName,
BeanReference requestCache, BeanReference sessionStrategy) { BeanReference requestCache, BeanReference sessionStrategy, boolean allowSessionCreation) {
this.defaultLoginProcessingUrl = defaultLoginProcessingUrl; this.defaultLoginProcessingUrl = defaultLoginProcessingUrl;
this.filterClassName = filterClassName; this.filterClassName = filterClassName;
this.requestCache = requestCache; this.requestCache = requestCache;
this.sessionStrategy = sessionStrategy; this.sessionStrategy = sessionStrategy;
this.allowSessionCreation = allowSessionCreation;
} }
public BeanDefinition parse(Element elt, ParserContext pc) { public BeanDefinition parse(Element elt, ParserContext pc) {
@ -135,6 +138,7 @@ public class FormLoginBeanDefinitionParser {
} }
} }
failureHandler.addPropertyValue("defaultFailureUrl", authenticationFailureUrl); failureHandler.addPropertyValue("defaultFailureUrl", authenticationFailureUrl);
failureHandler.addPropertyValue("allowSessionCreation", allowSessionCreation);
filterBuilder.addPropertyValue("authenticationFailureHandler", failureHandler.getBeanDefinition()); filterBuilder.addPropertyValue("authenticationFailureHandler", failureHandler.getBeanDefinition());
} }

View File

@ -16,14 +16,12 @@
package org.springframework.security.core.userdetails.memory; package org.springframework.security.core.userdetails.memory;
import static org.junit.Assert.*; import static org.junit.Assert.*;
import junit.framework.TestCase;
import org.junit.Test; import org.junit.Test;
import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User; import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.core.userdetails.memory.UserMap;
/** /**

View File

@ -0,0 +1,14 @@
package org.springframework.security.web;
/**
* Well-known keys which are used to store Spring Security information in request or session scope.
*
* @author Luke Taylor
* @since 3.0.3
*/
public final class WebAttributes {
public static final String ACCESS_DENIED_403 = "SPRING_SECURITY_403_EXCEPTION";
public static final String AUTHENTICATION_EXCEPTION = "SPRING_SECURITY_LAST_EXCEPTION";
public static final String LAST_USERNAME = "SPRING_SECURITY_LAST_USERNAME";
public static final String SAVED_REQUEST = "SPRING_SECURITY_SAVED_REQUEST_KEY";
}

View File

@ -25,6 +25,7 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.security.access.AccessDeniedException; import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.web.WebAttributes;
/** /**
@ -35,14 +36,17 @@ import org.springframework.security.access.AccessDeniedException;
* Being a "forward", the <code>SecurityContextHolder</code> will remain * Being a "forward", the <code>SecurityContextHolder</code> will remain
* populated. This is of benefit if the view (or a tag library or macro) wishes to access the * populated. This is of benefit if the view (or a tag library or macro) wishes to access the
* <code>SecurityContextHolder</code>. The request scope will also be populated with the exception itself, available * <code>SecurityContextHolder</code>. The request scope will also be populated with the exception itself, available
* from the key {@link #SPRING_SECURITY_ACCESS_DENIED_EXCEPTION_KEY}. * from the key {@link WebAttributes.ACCESS_DENIED_403}.
* *
* @author Ben Alex * @author Ben Alex
*/ */
public class AccessDeniedHandlerImpl implements AccessDeniedHandler { public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
//~ Static fields/initializers ===================================================================================== //~ Static fields/initializers =====================================================================================
/**
public static final String SPRING_SECURITY_ACCESS_DENIED_EXCEPTION_KEY = "SPRING_SECURITY_403_EXCEPTION"; * @deprecated Use the value in {@link WebAttributes} directly.
*/
@Deprecated
public static final String SPRING_SECURITY_ACCESS_DENIED_EXCEPTION_KEY = WebAttributes.ACCESS_DENIED_403;
protected static final Log logger = LogFactory.getLog(AccessDeniedHandlerImpl.class); protected static final Log logger = LogFactory.getLog(AccessDeniedHandlerImpl.class);
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
@ -56,7 +60,7 @@ public class AccessDeniedHandlerImpl implements AccessDeniedHandler {
if (!response.isCommitted()) { if (!response.isCommitted()) {
if (errorPage != null) { if (errorPage != null) {
// Put exception into request scope (perhaps of use to a view) // Put exception into request scope (perhaps of use to a view)
request.setAttribute(SPRING_SECURITY_ACCESS_DENIED_EXCEPTION_KEY, accessDeniedException); request.setAttribute(WebAttributes.ACCESS_DENIED_403, accessDeniedException);
// Set the 403 status code. // Set the 403 status code.
response.setStatus(HttpServletResponse.SC_FORBIDDEN); response.setStatus(HttpServletResponse.SC_FORBIDDEN);

View File

@ -23,7 +23,6 @@ import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.context.ApplicationEventPublisherAware;
@ -37,6 +36,7 @@ import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.SpringSecurityMessageSource; import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy; import org.springframework.security.web.authentication.session.NullAuthenticatedSessionStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy; import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.util.UrlUtils; import org.springframework.security.web.util.UrlUtils;
@ -76,20 +76,16 @@ import org.springframework.web.filter.GenericFilterBean;
* *
* <h4>Authentication Failure</h4> * <h4>Authentication Failure</h4>
* *
* If authentication fails, the resulting <tt>AuthenticationException</tt> will be placed into the <tt>HttpSession</tt> * If authentication fails, it will delegate to the configured {@link AuthenticationFailureHandler} to allow the
* with the attribute defined by {@link #SPRING_SECURITY_LAST_EXCEPTION_KEY}. It will then delegate to the configured * failure information to be conveyed to the client. The default implementation is
* {@link AuthenticationFailureHandler} to allow the failure information to be conveyed to the client. * {@link SimpleUrlAuthenticationFailureHandler}, which sends a 401 error code to the client. It may also be configured
* The default implementation is {@link SimpleUrlAuthenticationFailureHandler}, which sends a 401 error code to the * with a failure URL as an alternative. Again you can inject whatever behaviour you require here.
* client. It may also be configured with a failure URL as an alternative. Again you can inject whatever
* behaviour you require here.
* *
* <h4>Event Publication</h4> * <h4>Event Publication</h4>
* *
* If authentication is successful, an * If authentication is successful, an {@link InteractiveAuthenticationSuccessEvent} will be published via the
* {@link org.springframework.security.authentication.event.InteractiveAuthenticationSuccessEvent * application context. No events will be published if authentication was unsuccessful, because this would generally be
* InteractiveAuthenticationSuccessEvent} will be published via the application context. No events will be published if * recorded via an {@code AuthenticationManager}-specific application event.
* authentication was unsuccessful, because this would generally be recorded via an
* <tt>AuthenticationManager</tt>-specific application event.
* <p> * <p>
* The filter has an optional attribute <tt>invalidateSessionOnSuccessfulAuthentication</tt> that will invalidate * The filter has an optional attribute <tt>invalidateSessionOnSuccessfulAuthentication</tt> that will invalidate
* the current session on successful authentication. This is to protect against session fixation attacks (see * the current session on successful authentication. This is to protect against session fixation attacks (see
@ -106,7 +102,11 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
ApplicationEventPublisherAware, MessageSourceAware { ApplicationEventPublisherAware, MessageSourceAware {
//~ Static fields/initializers ===================================================================================== //~ Static fields/initializers =====================================================================================
public static final String SPRING_SECURITY_LAST_EXCEPTION_KEY = "SPRING_SECURITY_LAST_EXCEPTION"; /**
* @deprecated Use the value in {@link WebAttributes} directly.
*/
@Deprecated
public static final String SPRING_SECURITY_LAST_EXCEPTION_KEY = WebAttributes.AUTHENTICATION_EXCEPTION;
//~ Instance fields ================================================================================================ //~ Instance fields ================================================================================================
@ -321,12 +321,6 @@ public abstract class AbstractAuthenticationProcessingFilter extends GenericFilt
logger.debug("Delegating to authentication failure handler" + failureHandler); logger.debug("Delegating to authentication failure handler" + failureHandler);
} }
HttpSession session = request.getSession(false);
if (session != null || allowSessionCreation) {
request.getSession().setAttribute(SPRING_SECURITY_LAST_EXCEPTION_KEY, failed);
}
rememberMeServices.loginFail(request, response); rememberMeServices.loginFail(request, response);
failureHandler.onAuthenticationFailure(request, response, failed); failureHandler.onAuthenticationFailure(request, response, failed);

View File

@ -5,10 +5,12 @@ import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.DefaultRedirectStrategy; import org.springframework.security.web.DefaultRedirectStrategy;
import org.springframework.security.web.RedirectStrategy; import org.springframework.security.web.RedirectStrategy;
import org.springframework.security.web.util.UrlUtils; import org.springframework.security.web.util.UrlUtils;
@ -31,6 +33,7 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
private String defaultFailureUrl; private String defaultFailureUrl;
private boolean forwardToDestination = false; private boolean forwardToDestination = false;
private boolean allowSessionCreation = true;
private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy(); private RedirectStrategy redirectStrategy = new DefaultRedirectStrategy();
public SimpleUrlAuthenticationFailureHandler() { public SimpleUrlAuthenticationFailureHandler() {
@ -40,6 +43,12 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
setDefaultFailureUrl(defaultFailureUrl); setDefaultFailureUrl(defaultFailureUrl);
} }
/**
* Performs the redirect or forward to the {@code defaultFailureUrl} if set, otherwise returns a 401 error code.
* <p>
* If redirecting or forwarding, {@code saveException} will be called to cache the exception for use in
* the target view.
*/
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
AuthenticationException exception) throws IOException, ServletException { AuthenticationException exception) throws IOException, ServletException {
@ -48,6 +57,8 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + exception.getMessage()); response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed: " + exception.getMessage());
} else { } else {
saveException(request, exception);
if (forwardToDestination) { if (forwardToDestination) {
logger.debug("Forwarding to " + defaultFailureUrl); logger.debug("Forwarding to " + defaultFailureUrl);
@ -59,6 +70,25 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
} }
} }
/**
* Caches the {@code AuthenticationException} for use in view rendering.
* <p>
* If {@code forwardToDestination} is set to true, request scope will be used, otherwise it will attempt to store
* the exception in the session. If there is no session and {@code allowSessionCreation} is {@code true} a session
* will be created. Otherwise the exception will not be stored.
*/
protected final void saveException(HttpServletRequest request, AuthenticationException exception) {
if (forwardToDestination) {
request.setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
} else {
HttpSession session = request.getSession(false);
if (session != null || allowSessionCreation) {
request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, exception);
}
}
}
/** /**
* The URL which will be used as the failure destination. * The URL which will be used as the failure destination.
* *
@ -92,4 +122,12 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
protected RedirectStrategy getRedirectStrategy() { protected RedirectStrategy getRedirectStrategy() {
return redirectStrategy; return redirectStrategy;
} }
protected boolean isAllowSessionCreation() {
return allowSessionCreation;
}
public void setAllowSessionCreation(boolean allowSessionCreation) {
this.allowSessionCreation = allowSessionCreation;
}
} }

View File

@ -19,7 +19,7 @@ import org.springframework.security.authentication.event.InteractiveAuthenticati
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource; import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.web.filter.GenericFilterBean; import org.springframework.web.filter.GenericFilterBean;
@ -176,7 +176,7 @@ public abstract class AbstractPreAuthenticatedProcessingFilter extends GenericFi
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
logger.debug("Cleared security context due to exception", failed); logger.debug("Cleared security context due to exception", failed);
} }
request.getSession().setAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, failed); request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, failed);
} }
/** /**

View File

@ -13,7 +13,7 @@ import javax.servlet.http.HttpSession;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.savedrequest.DefaultSavedRequest; import org.springframework.security.web.WebAttributes;
/** /**
* The default implementation of {@link SessionAuthenticationStrategy}. * The default implementation of {@link SessionAuthenticationStrategy}.
@ -44,7 +44,7 @@ public class SessionFixationProtectionStrategy implements SessionAuthenticationS
* In the case where the attributes will not be migrated, this field allows a list of named attributes * In the case where the attributes will not be migrated, this field allows a list of named attributes
* which should <em>not</em> be discarded. * which should <em>not</em> be discarded.
*/ */
private List<String> retainedAttributes = Arrays.asList(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY); private List<String> retainedAttributes = Arrays.asList(WebAttributes.SAVED_REQUEST);
/** /**
* If set to <tt>true</tt>, a session will always be created, even if one didn't exist at the start of the request. * If set to <tt>true</tt>, a session will always be created, even if one didn't exist at the start of the request.

View File

@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter; import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices; import org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices;
@ -100,7 +101,7 @@ public class DefaultLoginPageGeneratingFilter extends GenericFilterBean {
if(session != null) { if(session != null) {
lastUser = (String) session.getAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY); lastUser = (String) session.getAttribute(UsernamePasswordAuthenticationFilter.SPRING_SECURITY_LAST_USERNAME_KEY);
AuthenticationException ex = (AuthenticationException) session.getAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY); AuthenticationException ex = (AuthenticationException) session.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION);
errorMsg = ex != null ? ex.getMessage() : "none"; errorMsg = ex != null ? ex.getMessage() : "none";
if (lastUser == null) { if (lastUser == null) {
lastUser = ""; lastUser = "";

View File

@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.security.web.PortResolver; import org.springframework.security.web.PortResolver;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.util.UrlUtils; import org.springframework.security.web.util.UrlUtils;
import org.springframework.util.Assert; import org.springframework.util.Assert;
@ -51,8 +52,11 @@ public class DefaultSavedRequest implements SavedRequest {
//~ Static fields/initializers ===================================================================================== //~ Static fields/initializers =====================================================================================
protected static final Log logger = LogFactory.getLog(DefaultSavedRequest.class); protected static final Log logger = LogFactory.getLog(DefaultSavedRequest.class);
/**
public static final String SPRING_SECURITY_SAVED_REQUEST_KEY = "SPRING_SECURITY_SAVED_REQUEST_KEY"; * @deprecated Use the value in {@link WebAttributes} directly.
*/
@Deprecated
public static final String SPRING_SECURITY_SAVED_REQUEST_KEY = WebAttributes.SAVED_REQUEST;
private static final String HEADER_IF_NONE_MATCH = "If-None-Match"; private static final String HEADER_IF_NONE_MATCH = "If-None-Match";

View File

@ -8,6 +8,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.security.web.PortResolver; import org.springframework.security.web.PortResolver;
import org.springframework.security.web.PortResolverImpl; import org.springframework.security.web.PortResolverImpl;
import org.springframework.security.web.WebAttributes;
/** /**
* <tt>RequestCache</tt> which stores the <tt>SavedRequest</tt> in the HttpSession. * <tt>RequestCache</tt> which stores the <tt>SavedRequest</tt> in the HttpSession.
@ -34,7 +35,7 @@ public class HttpSessionRequestCache implements RequestCache {
if (createSessionAllowed || request.getSession(false) != null) { if (createSessionAllowed || request.getSession(false) != null) {
// Store the HTTP request itself. Used by AbstractAuthenticationProcessingFilter // Store the HTTP request itself. Used by AbstractAuthenticationProcessingFilter
// for redirection after successful authentication (SEC-29) // for redirection after successful authentication (SEC-29)
request.getSession().setAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, savedRequest); request.getSession().setAttribute(WebAttributes.SAVED_REQUEST, savedRequest);
logger.debug("DefaultSavedRequest added to Session: " + savedRequest); logger.debug("DefaultSavedRequest added to Session: " + savedRequest);
} }
} }
@ -45,7 +46,7 @@ public class HttpSessionRequestCache implements RequestCache {
HttpSession session = currentRequest.getSession(false); HttpSession session = currentRequest.getSession(false);
if (session != null) { if (session != null) {
return (DefaultSavedRequest) session.getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY); return (DefaultSavedRequest) session.getAttribute(WebAttributes.SAVED_REQUEST);
} }
return null; return null;
@ -56,7 +57,7 @@ public class HttpSessionRequestCache implements RequestCache {
if (session != null) { if (session != null) {
logger.debug("Removing DefaultSavedRequest from session if present"); logger.debug("Removing DefaultSavedRequest from session if present");
session.removeAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY); session.removeAttribute(WebAttributes.SAVED_REQUEST);
} }
} }

View File

@ -41,6 +41,7 @@ import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.AuthenticationEntryPoint; import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.savedrequest.HttpSessionRequestCache; import org.springframework.security.web.savedrequest.HttpSessionRequestCache;
import org.springframework.security.web.savedrequest.DefaultSavedRequest; import org.springframework.security.web.savedrequest.DefaultSavedRequest;
import org.springframework.security.web.util.ThrowableAnalyzer; import org.springframework.security.web.util.ThrowableAnalyzer;
@ -65,7 +66,7 @@ public class ExceptionTranslationFilterTests {
return null; return null;
} }
DefaultSavedRequest savedRequest = (DefaultSavedRequest) session.getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY); DefaultSavedRequest savedRequest = (DefaultSavedRequest) session.getAttribute(WebAttributes.SAVED_REQUEST);
return savedRequest.getRedirectUrl(); return savedRequest.getRedirectUrl();
} }
@ -127,8 +128,7 @@ public class ExceptionTranslationFilterTests {
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
filter.doFilter(request, response, fc); filter.doFilter(request, response, fc);
assertEquals(403, response.getStatus()); assertEquals(403, response.getStatus());
assertEquals(AccessDeniedException.class, request.getAttribute( assertEquals(AccessDeniedException.class, request.getAttribute(WebAttributes.ACCESS_DENIED_403).getClass());
AccessDeniedHandlerImpl.SPRING_SECURITY_ACCESS_DENIED_EXCEPTION_KEY).getClass());
} }
@Test @Test
@ -198,7 +198,7 @@ public class ExceptionTranslationFilterTests {
doThrow(new BadCredentialsException("")).when(fc).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class)); doThrow(new BadCredentialsException("")).when(fc).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));
request.setMethod("POST"); request.setMethod("POST");
filter.doFilter(request, new MockHttpServletResponse(), fc); filter.doFilter(request, new MockHttpServletResponse(), fc);
assertTrue(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY) == null); assertTrue(request.getSession().getAttribute(WebAttributes.SAVED_REQUEST) == null);
} }
@Test(expected=IllegalArgumentException.class) @Test(expected=IllegalArgumentException.class)

View File

@ -58,6 +58,7 @@ import org.springframework.security.web.savedrequest.DefaultSavedRequest;
* *
* @author Ben Alex * @author Ben Alex
*/ */
@SuppressWarnings("deprecation")
public class AbstractAuthenticationProcessingFilterTests extends TestCase { public class AbstractAuthenticationProcessingFilterTests extends TestCase {
SavedRequestAwareAuthenticationSuccessHandler successHandler; SavedRequestAwareAuthenticationSuccessHandler successHandler;
SimpleUrlAuthenticationFailureHandler failureHandler; SimpleUrlAuthenticationFailureHandler failureHandler;

View File

@ -16,6 +16,7 @@ import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.SpringSecurityMessageSource; import org.springframework.security.core.SpringSecurityMessageSource;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter; import org.springframework.security.web.authentication.ui.DefaultLoginPageGeneratingFilter;
/** /**
@ -67,7 +68,7 @@ public class DefaultLoginPageGeneratingFilterTests {
String message = messages.getMessage( String message = messages.getMessage(
"AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials", Locale.KOREA); "AbstractUserDetailsAuthenticationProvider.badCredentials", "Bad credentials", Locale.KOREA);
System.out.println("Message: " + message); System.out.println("Message: " + message);
request.getSession().setAttribute(AbstractAuthenticationProcessingFilter.SPRING_SECURITY_LAST_EXCEPTION_KEY, new BadCredentialsException(message)); request.getSession().setAttribute(WebAttributes.AUTHENTICATION_EXCEPTION, new BadCredentialsException(message));
filter.doFilter(request, new MockHttpServletResponse(), chain); filter.doFilter(request, new MockHttpServletResponse(), chain);
} }

View File

@ -5,6 +5,7 @@ import static org.junit.Assert.*;
import org.junit.Test; import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.WebAttributes;
/** /**
* *
@ -20,7 +21,7 @@ public class HttpSessionRequestCacheTests {
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/destination"); MockHttpServletRequest request = new MockHttpServletRequest("GET", "/destination");
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
cache.saveRequest(request, response); cache.saveRequest(request, response);
assertNotNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY)); assertNotNull(request.getSession().getAttribute(WebAttributes.SAVED_REQUEST));
assertNotNull(cache.getRequest(request, response)); assertNotNull(cache.getRequest(request, response));
MockHttpServletRequest newRequest = new MockHttpServletRequest("POST", "/destination"); MockHttpServletRequest newRequest = new MockHttpServletRequest("POST", "/destination");

View File

@ -6,6 +6,7 @@ import org.junit.Test;
import org.springframework.mock.web.MockFilterChain; import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.web.WebAttributes;
public class RequestCacheAwareFilterTests { public class RequestCacheAwareFilterTests {
@ -17,9 +18,9 @@ public class RequestCacheAwareFilterTests {
MockHttpServletRequest request = new MockHttpServletRequest("POST", "/destination"); MockHttpServletRequest request = new MockHttpServletRequest("POST", "/destination");
MockHttpServletResponse response = new MockHttpServletResponse(); MockHttpServletResponse response = new MockHttpServletResponse();
cache.saveRequest(request, response); cache.saveRequest(request, response);
assertNotNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY)); assertNotNull(request.getSession().getAttribute(WebAttributes.SAVED_REQUEST));
filter.doFilter(request, response, new MockFilterChain()); filter.doFilter(request, response, new MockFilterChain());
assertNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY)); assertNull(request.getSession().getAttribute(WebAttributes.SAVED_REQUEST));
} }
} }

View File

@ -10,8 +10,8 @@ import org.junit.Test;
import org.springframework.mock.web.MockHttpServletRequest; import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse; import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy; import org.springframework.security.web.authentication.session.SessionFixationProtectionStrategy;
import org.springframework.security.web.savedrequest.DefaultSavedRequest;
/** /**
* *
@ -48,12 +48,12 @@ public class DefaultSessionAuthenticationStrategyTests {
HttpServletRequest request = new MockHttpServletRequest(); HttpServletRequest request = new MockHttpServletRequest();
HttpSession session = request.getSession(); HttpSession session = request.getSession();
session.setAttribute("blah", "blah"); session.setAttribute("blah", "blah");
session.setAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY, "DefaultSavedRequest"); session.setAttribute(WebAttributes.SAVED_REQUEST, "DefaultSavedRequest");
strategy.onAuthentication(mock(Authentication.class), request, new MockHttpServletResponse()); strategy.onAuthentication(mock(Authentication.class), request, new MockHttpServletResponse());
assertNull(request.getSession().getAttribute("blah")); assertNull(request.getSession().getAttribute("blah"));
assertNotNull(request.getSession().getAttribute(DefaultSavedRequest.SPRING_SECURITY_SAVED_REQUEST_KEY)); assertNotNull(request.getSession().getAttribute(WebAttributes.SAVED_REQUEST));
} }
@Test @Test