SEC-1058: Substantial refactoring of AbstractProcessingFilter to use AuthenticationFailureHandler strategy. Also changed attemptAuthentication method to take a response object and have the option of returning null, to allow OpenIDAuthenticationProcessingFilter to work without having to throw exceptions between the template methods (which made the logic very hard to follow). The OpenID filter now redirects to the OpenID provider service from this method, rather than treating it as a temporary failure and throwing OpenIDAuthenticationRequiredException.
This commit is contained in:
+4
-2
@@ -24,6 +24,7 @@ import org.springframework.security.ui.logout.SecurityContextLogoutHandler;
|
||||
import org.springframework.security.util.UrlUtils;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
@@ -61,7 +62,8 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(sessionRegistry, "SessionRegistry required");
|
||||
Assert.isTrue(UrlUtils.isValidRedirectUrl(expiredUrl), expiredUrl + " isn't a valid redirect URL");
|
||||
Assert.isTrue(expiredUrl == null || UrlUtils.isValidRedirectUrl(expiredUrl),
|
||||
expiredUrl + " isn't a valid redirect URL");
|
||||
}
|
||||
|
||||
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
@@ -120,7 +122,7 @@ public class ConcurrentSessionFilter extends SpringSecurityFilter implements Ini
|
||||
}
|
||||
|
||||
public void setLogoutHandlers(LogoutHandler[] handlers) {
|
||||
Assert.notNull(handlers);
|
||||
Assert.notNull(handlers);
|
||||
this.handlers = handlers;
|
||||
}
|
||||
|
||||
|
||||
@@ -157,7 +157,7 @@ abstract class ConfigUtils {
|
||||
* If not empty or starting with "$" (potential placeholder), "/" or "http" it will raise an error.
|
||||
*/
|
||||
static void validateHttpRedirect(String url, ParserContext pc, Object source) {
|
||||
if (UrlUtils.isValidRedirectUrl(url) || url.startsWith("$")) {
|
||||
if (!StringUtils.hasText(url) || UrlUtils.isValidRedirectUrl(url) || url.startsWith("$")) {
|
||||
return;
|
||||
}
|
||||
pc.getReaderContext().warning(url + " is not a valid redirect URL (must start with '/' or http(s))", source);
|
||||
|
||||
+19
-11
@@ -8,6 +8,7 @@ import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.BeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.security.ui.SavedRequestAwareAuthenticationSuccessHandler;
|
||||
import org.springframework.security.ui.SimpleUrlAuthenticationFailureHandler;
|
||||
import org.springframework.security.ui.webapp.AuthenticationProcessingFilterEntryPoint;
|
||||
import org.springframework.security.ui.webapp.DefaultLoginPageGeneratingFilter;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -37,6 +38,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
||||
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_FAILURE_HANDLER_REF = "authentication-failure-handler-ref";
|
||||
|
||||
private String defaultLoginProcessingUrl;
|
||||
private String filterClassName;
|
||||
@@ -56,6 +58,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
||||
String authenticationFailureUrl = null;
|
||||
String alwaysUseDefault = null;
|
||||
String successHandlerRef = null;
|
||||
String failureHandlerRef = null;
|
||||
|
||||
Object source = null;
|
||||
|
||||
@@ -82,18 +85,18 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
||||
alwaysUseDefault = elt.getAttribute(ATT_ALWAYS_USE_DEFAULT_TARGET_URL);
|
||||
loginPage = elt.getAttribute(ATT_LOGIN_PAGE);
|
||||
successHandlerRef = elt.getAttribute(ATT_SUCCESS_HANDLER_REF);
|
||||
failureHandlerRef = elt.getAttribute(ATT_FAILURE_HANDLER_REF);
|
||||
|
||||
if (!StringUtils.hasText(loginPage)) {
|
||||
loginPage = null;
|
||||
}
|
||||
ConfigUtils.validateHttpRedirect(loginPage, pc, source);
|
||||
|
||||
}
|
||||
|
||||
ConfigUtils.registerProviderManagerIfNecessary(pc);
|
||||
|
||||
filterBean = createFilterBean(loginUrl, defaultTargetUrl, alwaysUseDefault, loginPage, authenticationFailureUrl,
|
||||
successHandlerRef);
|
||||
successHandlerRef, failureHandlerRef);
|
||||
filterBean.setSource(source);
|
||||
filterBean.getPropertyValues().addPropertyValue("authenticationManager",
|
||||
new RuntimeBeanReference(BeanIds.AUTHENTICATION_MANAGER));
|
||||
@@ -123,7 +126,7 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
||||
}
|
||||
|
||||
private RootBeanDefinition createFilterBean(String loginUrl, String defaultTargetUrl, String alwaysUseDefault,
|
||||
String loginPage, String authenticationFailureUrl, String successHandlerRef) {
|
||||
String loginPage, String authenticationFailureUrl, String successHandlerRef, String failureHandlerRef) {
|
||||
|
||||
BeanDefinitionBuilder filterBuilder = BeanDefinitionBuilder.rootBeanDefinition(filterClassName);
|
||||
|
||||
@@ -144,17 +147,22 @@ public class FormLoginBeanDefinitionParser implements BeanDefinitionParser {
|
||||
filterBuilder.addPropertyValue("successHandler", successHandler.getBeanDefinition());
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(authenticationFailureUrl)) {
|
||||
// Fallback to redisplaying the custom login page, if one was specified
|
||||
if (StringUtils.hasText(loginPage)) {
|
||||
authenticationFailureUrl = loginPage;
|
||||
} else {
|
||||
authenticationFailureUrl = DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL;
|
||||
if (StringUtils.hasText(failureHandlerRef)) {
|
||||
filterBuilder.addPropertyReference("failureHandler", failureHandlerRef);
|
||||
} else {
|
||||
BeanDefinitionBuilder failureHandler = BeanDefinitionBuilder.rootBeanDefinition(SimpleUrlAuthenticationFailureHandler.class);
|
||||
if (!StringUtils.hasText(authenticationFailureUrl)) {
|
||||
// Fall back to redisplaying the custom login page, if one was specified.
|
||||
if (StringUtils.hasText(loginPage)) {
|
||||
authenticationFailureUrl = loginPage;
|
||||
} else {
|
||||
authenticationFailureUrl = DEF_FORM_LOGIN_AUTHENTICATION_FAILURE_URL;
|
||||
}
|
||||
}
|
||||
failureHandler.addPropertyValue("defaultFailureUrl", authenticationFailureUrl);
|
||||
filterBuilder.addPropertyValue("failureHandler", failureHandler.getBeanDefinition());
|
||||
}
|
||||
|
||||
filterBuilder.addPropertyValue("authenticationFailureUrl", authenticationFailureUrl);
|
||||
|
||||
return (RootBeanDefinition) filterBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import org.springframework.security.SpringSecurityMessageSource;
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.AuthenticationManager;
|
||||
import org.springframework.security.util.RedirectUtils;
|
||||
import org.springframework.security.util.SessionUtils;
|
||||
import org.springframework.security.util.UrlUtils;
|
||||
|
||||
@@ -44,8 +43,6 @@ import org.springframework.util.Assert;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
@@ -128,45 +125,24 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
//~ Instance fields ================================================================================================
|
||||
|
||||
protected ApplicationEventPublisher eventPublisher;
|
||||
|
||||
protected AuthenticationDetailsSource authenticationDetailsSource = new WebAuthenticationDetailsSource();
|
||||
|
||||
private AuthenticationManager authenticationManager;
|
||||
|
||||
protected MessageSourceAccessor messages = SpringSecurityMessageSource.getAccessor();
|
||||
|
||||
private Properties exceptionMappings = new Properties();
|
||||
|
||||
/**
|
||||
/*
|
||||
* Delay use of NullRememberMeServices until initialization so that namespace has a chance to inject
|
||||
* the RememberMeServices implementation into custom implementations.
|
||||
*/
|
||||
private RememberMeServices rememberMeServices = null;
|
||||
|
||||
/** Where to redirect the browser to if authentication fails */
|
||||
private String authenticationFailureUrl;
|
||||
|
||||
/**
|
||||
* The URL destination that this filter intercepts and processes (usually
|
||||
* something like <code>/j_spring_security_check</code>)
|
||||
*/
|
||||
private String filterProcessesUrl = getDefaultFilterProcessesUrl();
|
||||
|
||||
/**
|
||||
* Indicates if the filter chain should be continued prior to delegation to
|
||||
* {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse,
|
||||
* Authentication)}, which may be useful in certain environment (eg
|
||||
* Tapestry). Defaults to <code>false</code>.
|
||||
*/
|
||||
private boolean continueChainBeforeSuccessfulAuthentication = false;
|
||||
|
||||
/**
|
||||
* If true, causes any redirection URLs to be calculated minus the protocol
|
||||
* and context path (defaults to false).
|
||||
*/
|
||||
protected boolean useRelativeContext = false;
|
||||
|
||||
|
||||
/**
|
||||
* Tells if we on successful authentication should invalidate the
|
||||
* current session. This is a common guard against session fixation attacks.
|
||||
@@ -185,19 +161,16 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
|
||||
private boolean allowSessionCreation = true;
|
||||
|
||||
private boolean serverSideRedirect = false;
|
||||
|
||||
private SessionRegistry sessionRegistry;
|
||||
|
||||
private AuthenticationSuccessHandler successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||
private AuthenticationFailureHandler failureHandler = null;
|
||||
private AuthenticationFailureHandler failureHandler = new SimpleUrlAuthenticationFailureHandler();
|
||||
|
||||
//~ 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.isTrue(UrlUtils.isValidRedirectUrl(authenticationFailureUrl), authenticationFailureUrl + " isn't a valid redirect URL");
|
||||
Assert.notNull(authenticationManager, "authenticationManager must be specified");
|
||||
|
||||
if (rememberMeServices == null) {
|
||||
@@ -206,19 +179,26 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs actual authentication.
|
||||
*
|
||||
* @param request from which to extract parameters and perform the
|
||||
* authentication
|
||||
*
|
||||
* @return the authenticated user
|
||||
*
|
||||
* @throws AuthenticationException if authentication fails
|
||||
* 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:
|
||||
* <ol>
|
||||
* <li>An <tt>Authentication</tt> object is returned.
|
||||
* The {@link #successfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* successfulAuthentication} method will be invoked</li>
|
||||
* <li>An <tt>AuthenticationException</tt> occurs during authentication.
|
||||
* The {@link #unSuccessfulAuthentication(HttpServletRequest, HttpServletResponse, Authentication)
|
||||
* unSuccessfulAuthentication} method will be invoked</li>
|
||||
* <li>Null is returned, indicating that the authentication process is incomplete.
|
||||
* The method will then return immediately, assuming that the subclass has done any necessary work (such as
|
||||
* redirects) to continue the authentication process. The assumption is that a later request will be received
|
||||
* by this method where the returned <tt>Authentication</tt> object is not null.
|
||||
* </ol>
|
||||
*/
|
||||
public abstract Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException;
|
||||
|
||||
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException,
|
||||
ServletException {
|
||||
public void doFilterHttp(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||
throws IOException, ServletException {
|
||||
|
||||
if (!requiresAuthentication(request, response)) {
|
||||
chain.doFilter(request, response);
|
||||
@@ -233,8 +213,11 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
Authentication authResult;
|
||||
|
||||
try {
|
||||
onPreAuthentication(request, response);
|
||||
authResult = attemptAuthentication(request);
|
||||
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
|
||||
@@ -251,35 +234,17 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
successfulAuthentication(request, response, authResult);
|
||||
}
|
||||
|
||||
protected void onPreAuthentication(HttpServletRequest request, HttpServletResponse response)
|
||||
throws AuthenticationException, IOException {
|
||||
}
|
||||
|
||||
protected void onUnsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException failed) throws IOException {
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Indicates whether this filter should attempt to process a login request
|
||||
* for the current invocation.
|
||||
* </p>
|
||||
* Indicates whether this filter should attempt to process a login request for the current invocation.
|
||||
* <p>
|
||||
* It strips any parameters from the "path" section of the request URL (such
|
||||
* as the jsessionid parameter in
|
||||
* <em>http://host/myapp/index.html;jsessionid=blah</em>) before matching
|
||||
* against the <code>filterProcessesUrl</code> property.
|
||||
* </p>
|
||||
* <p>
|
||||
* Subclasses may override for special requirements, such as Tapestry
|
||||
* integration.
|
||||
* </p>
|
||||
* Subclasses may override for special requirements, such as Tapestry integration.
|
||||
*
|
||||
* @param request as received from the filter chain
|
||||
* @param response as received from the filter chain
|
||||
*
|
||||
* @return <code>true</code> if the filter should attempt authentication,
|
||||
* <code>false</code> otherwise
|
||||
* @return <code>true</code> if the filter should attempt authentication, <code>false</code> otherwise.
|
||||
*/
|
||||
protected boolean requiresAuthentication(HttpServletRequest request, HttpServletResponse response) {
|
||||
String uri = request.getRequestURI();
|
||||
@@ -297,6 +262,41 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
return uri.endsWith(request.getContextPath() + filterProcessesUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs actual authentication.
|
||||
* <p>
|
||||
* The implementation should do one of the following:
|
||||
* <ol>
|
||||
* <li>Return a populated authentication token for the authenticated user, indicating successful authentication</li>
|
||||
* <li>Return null, indicating that the authentication process is still in progress. Before returning, the
|
||||
* implementation should perform any additional work required to complete the process.</li>
|
||||
* <li>Throw an <tt>AuthenticationException</tt> if the authentication process fails</li>
|
||||
* </ol>
|
||||
*
|
||||
* @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.
|
||||
* <ol>
|
||||
* <li>Sets the successful <tt>Authentication</tt> object on the {@link SecurityContextHolder}</li>
|
||||
* <li>Performs any configured session migration behaviour</li>
|
||||
* <li>Informs the configured <tt>RememberMeServices</tt> of the successul login</li>
|
||||
* <li>Fires an {@link InteractiveAuthenticationSuccessEvent} via the configured
|
||||
* <tt>ApplicationEventPublisher</tt></li>
|
||||
* <li>Delegates additional behaviour to the {@link AuthenticationSuccessHandler}.</li>
|
||||
* </ol>
|
||||
*
|
||||
* @param authResult the object returned from the <tt>attemptAuthentication</tt> method.
|
||||
*/
|
||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authResult) throws IOException, ServletException {
|
||||
|
||||
@@ -310,28 +310,24 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
SessionUtils.startNewSessionIfRequired(request, migrateInvalidatedSessionAttributes, sessionRegistry);
|
||||
}
|
||||
|
||||
successHandler.onAuthenticationSuccess(request, response, authResult);
|
||||
|
||||
rememberMeServices.loginSuccess(request, response, authResult);
|
||||
|
||||
// Fire event
|
||||
if (this.eventPublisher != null) {
|
||||
eventPublisher.publishEvent(new InteractiveAuthenticationSuccessEvent(authResult, this.getClass()));
|
||||
}
|
||||
|
||||
successHandler.onAuthenticationSuccess(request, response, authResult);
|
||||
}
|
||||
|
||||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException failed) throws IOException, ServletException {
|
||||
SecurityContextHolder.getContext().setAuthentication(null);
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Updated SecurityContextHolder to contain null Authentication");
|
||||
}
|
||||
|
||||
String failureUrl = determineFailureUrl(request, failed);
|
||||
|
||||
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 {
|
||||
@@ -344,29 +340,9 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
catch (Exception ignored) {
|
||||
}
|
||||
|
||||
onUnsuccessfulAuthentication(request, response, failed);
|
||||
|
||||
rememberMeServices.loginFail(request, response);
|
||||
|
||||
if (failureUrl == null) {
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed:" + failed.getMessage());
|
||||
} else if (serverSideRedirect){
|
||||
request.getRequestDispatcher(failureUrl).forward(request, response);
|
||||
} else {
|
||||
RedirectUtils.sendRedirect(request, response, failureUrl, useRelativeContext);
|
||||
}
|
||||
}
|
||||
|
||||
protected String determineFailureUrl(HttpServletRequest request, AuthenticationException failed) {
|
||||
return exceptionMappings.getProperty(failed.getClass().getName(), authenticationFailureUrl);
|
||||
}
|
||||
|
||||
public String getAuthenticationFailureUrl() {
|
||||
return authenticationFailureUrl;
|
||||
}
|
||||
|
||||
public void setAuthenticationFailureUrl(String authenticationFailureUrl) {
|
||||
this.authenticationFailureUrl = authenticationFailureUrl;
|
||||
failureHandler.onAuthenticationFailure(request, response, failed);
|
||||
}
|
||||
|
||||
protected AuthenticationManager getAuthenticationManager() {
|
||||
@@ -378,21 +354,12 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies the default <code>filterProcessesUrl</code> for the
|
||||
* implementation.
|
||||
* Specifies the default <code>filterProcessesUrl</code> for the implementation.
|
||||
*
|
||||
* @return the default <code>filterProcessesUrl</code>
|
||||
*/
|
||||
public abstract String getDefaultFilterProcessesUrl();
|
||||
|
||||
protected Properties getExceptionMappings() {
|
||||
return new Properties(exceptionMappings);
|
||||
}
|
||||
|
||||
public void setExceptionMappings(Properties exceptionMappings) {
|
||||
this.exceptionMappings = exceptionMappings;
|
||||
}
|
||||
|
||||
public String getFilterProcessesUrl() {
|
||||
return filterProcessesUrl;
|
||||
}
|
||||
@@ -409,6 +376,12 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
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 <code>false</code>.
|
||||
*/
|
||||
public void setContinueChainBeforeSuccessfulAuthentication(boolean continueChainBeforeSuccessfulAuthentication) {
|
||||
this.continueChainBeforeSuccessfulAuthentication = continueChainBeforeSuccessfulAuthentication;
|
||||
}
|
||||
@@ -439,10 +412,6 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
return authenticationDetailsSource;
|
||||
}
|
||||
|
||||
public void setUseRelativeContext(boolean useRelativeContext) {
|
||||
this.useRelativeContext = useRelativeContext;
|
||||
}
|
||||
|
||||
protected boolean getAllowSessionCreation() {
|
||||
return allowSessionCreation;
|
||||
}
|
||||
@@ -451,15 +420,6 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
||||
this.allowSessionCreation = allowSessionCreation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if we are to do a server side include of the error URL instead of a 302 redirect.
|
||||
*
|
||||
* @param serverSideRedirect
|
||||
*/
|
||||
public void setServerSideRedirect(boolean serverSideRedirect) {
|
||||
this.serverSideRedirect = serverSideRedirect;
|
||||
}
|
||||
|
||||
/**
|
||||
* The session registry needs to be set if session fixation attack protection is in use (and concurrent
|
||||
* session control is enabled).
|
||||
|
||||
+23
-2
@@ -4,11 +4,14 @@ import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.util.RedirectUtils;
|
||||
import org.springframework.security.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Uses the internal map of exceptions types to URLs to determine the destination on authentication failure. The keys
|
||||
@@ -26,7 +29,7 @@ public class ExceptionMappingAuthenticationFailureHandler extends SimpleUrlAuthe
|
||||
|
||||
@Override
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
AuthenticationException exception) throws IOException, ServletException {
|
||||
String url = failureUrlMap.get(exception.getClass().getName());
|
||||
|
||||
if (url != null) {
|
||||
@@ -36,5 +39,23 @@ public class ExceptionMappingAuthenticationFailureHandler extends SimpleUrlAuthe
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the map of exception types (by name) to URLs.
|
||||
*
|
||||
* @param failureUrlMap the map keyed by the fully-qualified name of the exception class, with the corresponding
|
||||
* failure URL as the value.
|
||||
*
|
||||
* @throws IllegalArgumentException if the entries are not Strings or the URL is not valid.
|
||||
*/
|
||||
public void setExceptionMappings(Map<?,?> failureUrlMap) {
|
||||
this.failureUrlMap.clear();
|
||||
for (Map.Entry<?,?> entry : failureUrlMap.entrySet()) {
|
||||
Object exception = entry.getKey();
|
||||
Object url = entry.getValue();
|
||||
Assert.isInstanceOf(String.class, exception, "Exception key must be a String (the exception classname).");
|
||||
Assert.isInstanceOf(String.class, url, "URL must be a String");
|
||||
Assert.isTrue(UrlUtils.isValidRedirectUrl((String)url), "Not a valid redirect URL: " + url);
|
||||
this.failureUrlMap.put((String)exception, (String)url);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@ import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.security.Authentication;
|
||||
import org.springframework.security.ui.savedrequest.SavedRequest;
|
||||
import org.springframework.security.util.RedirectUtils;
|
||||
import org.springframework.security.util.UrlUtils;
|
||||
import org.springframework.security.wrapper.SavedRequestAwareWrapper;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -163,7 +164,7 @@ public class SavedRequestAwareAuthenticationSuccessHandler implements Authentica
|
||||
* @param defaultTargetUrl
|
||||
*/
|
||||
public void setDefaultTargetUrl(String defaultTargetUrl) {
|
||||
Assert.isTrue(defaultTargetUrl.startsWith("/") | defaultTargetUrl.startsWith("http"),
|
||||
Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultTargetUrl),
|
||||
"defaultTarget must start with '/' or with 'http(s)'");
|
||||
this.defaultTargetUrl = defaultTargetUrl;
|
||||
}
|
||||
|
||||
+11
-3
@@ -2,11 +2,14 @@ package org.springframework.security.ui;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.util.RedirectUtils;
|
||||
import org.springframework.security.util.UrlUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* <tt>AuthenticationFailureHandler</tt> which performs a redirect to the value of the {@link #setDefaultFailureUrl
|
||||
@@ -31,11 +34,15 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
|
||||
private boolean useRelativeContext = false;
|
||||
|
||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response,
|
||||
AuthenticationException exception) throws IOException {
|
||||
AuthenticationException exception) throws IOException, ServletException {
|
||||
if (defaultFailureUrl == null) {
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed:" + exception.getMessage());
|
||||
} else {
|
||||
RedirectUtils.sendRedirect(request, response, defaultFailureUrl, useRelativeContext);
|
||||
if (forwardToDestination) {
|
||||
request.getRequestDispatcher(defaultFailureUrl).forward(request, response);
|
||||
} else {
|
||||
RedirectUtils.sendRedirect(request, response, defaultFailureUrl, useRelativeContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +51,8 @@ public class SimpleUrlAuthenticationFailureHandler implements AuthenticationFail
|
||||
*
|
||||
* @param defaultFailureUrl the failure URL, for example "/loginFailed.jsp".
|
||||
*/
|
||||
public void setDefaultTargetUrl(String defaultFailureUrl) {
|
||||
public void setDefaultFailureUrl(String defaultFailureUrl) {
|
||||
Assert.isTrue(UrlUtils.isValidRedirectUrl(defaultFailureUrl));
|
||||
this.defaultFailureUrl = defaultFailureUrl;
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -26,6 +26,7 @@ import org.springframework.security.util.TextUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
|
||||
@@ -53,7 +54,7 @@ public class AuthenticationProcessingFilter extends AbstractProcessingFilter {
|
||||
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException {
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
String username = obtainUsername(request);
|
||||
String password = obtainPassword(request);
|
||||
|
||||
|
||||
+6
-3
@@ -24,6 +24,7 @@ import org.springframework.security.util.PortMapperImpl;
|
||||
import org.springframework.security.util.PortResolver;
|
||||
import org.springframework.security.util.PortResolverImpl;
|
||||
import org.springframework.security.util.RedirectUrlBuilder;
|
||||
import org.springframework.security.util.UrlUtils;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
@@ -31,6 +32,7 @@ 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;
|
||||
|
||||
@@ -79,7 +81,8 @@ public class AuthenticationProcessingFilterEntryPoint implements AuthenticationE
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.hasLength(loginFormUrl, "loginFormUrl must be specified");
|
||||
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");
|
||||
}
|
||||
@@ -117,7 +120,7 @@ public class AuthenticationProcessingFilterEntryPoint implements AuthenticationE
|
||||
|
||||
if (redirectUrl == null) {
|
||||
String loginForm = determineUrlToUseForThisRequest(httpRequest, httpResponse, authException);
|
||||
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Server side forward to: " + loginForm);
|
||||
}
|
||||
@@ -246,7 +249,7 @@ public class AuthenticationProcessingFilterEntryPoint implements AuthenticationE
|
||||
*/
|
||||
public void setServerSideRedirect(boolean serverSideRedirect) {
|
||||
this.serverSideRedirect = serverSideRedirect;
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean isServerSideRedirect() {
|
||||
return serverSideRedirect;
|
||||
|
||||
@@ -15,13 +15,11 @@
|
||||
|
||||
package org.springframework.security.util;
|
||||
|
||||
import org.springframework.security.intercept.web.FilterInvocation;
|
||||
|
||||
import org.springframework.security.ui.savedrequest.SavedRequest;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.security.intercept.web.FilterInvocation;
|
||||
import org.springframework.security.ui.savedrequest.SavedRequest;
|
||||
|
||||
|
||||
/**
|
||||
* Provides static methods for composing URLs.<p>Placed into a separate class for visibility, so that changes to
|
||||
@@ -102,8 +100,11 @@ public final class UrlUtils {
|
||||
return buildRequestUrl(sr.getServletPath(), sr.getRequestURI(), sr.getContextPath(), sr.getPathInfo(),
|
||||
sr.getQueryString());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if the supplied URL starts with a "/" or "http".
|
||||
*/
|
||||
public static boolean isValidRedirectUrl(String url) {
|
||||
return !StringUtils.hasText(url) || url.startsWith("/") || url.toLowerCase().startsWith("http");
|
||||
return url.startsWith("/") || url.toLowerCase().startsWith("http");
|
||||
}
|
||||
}
|
||||
|
||||
+18
-16
@@ -55,6 +55,7 @@ import org.springframework.security.util.PortResolverImpl;
|
||||
*/
|
||||
public class AbstractProcessingFilterTests extends TestCase {
|
||||
SavedRequestAwareAuthenticationSuccessHandler successHandler;
|
||||
SimpleUrlAuthenticationFailureHandler failureHandler;
|
||||
//~ Methods ========================================================================================================
|
||||
|
||||
private MockHttpServletRequest createMockRequest() {
|
||||
@@ -102,6 +103,8 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
super.setUp();
|
||||
successHandler = new SavedRequestAwareAuthenticationSuccessHandler();
|
||||
successHandler.setDefaultTargetUrl("/logged_in.jsp");
|
||||
failureHandler = new SimpleUrlAuthenticationFailureHandler();
|
||||
failureHandler.setDefaultFailureUrl("/failed.jsp");
|
||||
SecurityContextHolder.clearContext();
|
||||
}
|
||||
|
||||
@@ -133,7 +136,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
// Setup our test object, to deny access
|
||||
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
|
||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||
filter.setFailureHandler(failureHandler);
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
@@ -143,11 +146,11 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
//Prepare again, this time using the exception mapping
|
||||
filter = new MockAbstractProcessingFilter(new AccountExpiredException("You're account is expired"));
|
||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||
|
||||
Properties exceptionMappings = filter.getExceptionMappings();
|
||||
ExceptionMappingAuthenticationFailureHandler failureHandler = new ExceptionMappingAuthenticationFailureHandler();
|
||||
filter.setFailureHandler(failureHandler);
|
||||
Properties exceptionMappings = new Properties();
|
||||
exceptionMappings.setProperty(AccountExpiredException.class.getName(), "/accountExpired.jsp");
|
||||
filter.setExceptionMappings(exceptionMappings);
|
||||
failureHandler.setExceptionMappings(exceptionMappings);
|
||||
response = new MockHttpServletResponse();
|
||||
|
||||
// Test
|
||||
@@ -186,7 +189,6 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager());
|
||||
filter.setFilterProcessesUrl("/p");
|
||||
filter.setAuthenticationFailureUrl("/fail");
|
||||
filter.afterPropertiesSet();
|
||||
|
||||
assertNotNull(filter.getRememberMeServices());
|
||||
@@ -194,7 +196,6 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
assertEquals(TokenBasedRememberMeServices.class, filter.getRememberMeServices().getClass());
|
||||
assertTrue(filter.getAuthenticationManager() != null);
|
||||
assertEquals("/p", filter.getFilterProcessesUrl());
|
||||
assertEquals("/fail", filter.getAuthenticationFailureUrl());
|
||||
}
|
||||
|
||||
public void testIgnoresAnyServletPathOtherThanFilterProcessesUrl() throws Exception {
|
||||
@@ -234,7 +235,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
filter.setFilterProcessesUrl("/j_mock_post");
|
||||
filter.setSuccessHandler(successHandler);
|
||||
filter.setAuthenticationFailureUrl("/failure.jsp");
|
||||
filter.setFailureHandler(failureHandler);
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
filter.afterPropertiesSet();
|
||||
|
||||
@@ -249,7 +250,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
public void testStartupDetectsInvalidAuthenticationManager() throws Exception {
|
||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||
filter.setFailureHandler(failureHandler);
|
||||
successHandler.setDefaultTargetUrl("/");
|
||||
filter.setSuccessHandler(successHandler);
|
||||
filter.setFilterProcessesUrl("/j_spring_security_check");
|
||||
@@ -264,7 +265,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
|
||||
public void testStartupDetectsInvalidFilterProcessesUrl() throws Exception {
|
||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||
filter.setFailureHandler(failureHandler);
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager());
|
||||
filter.setSuccessHandler(successHandler);
|
||||
filter.setFilterProcessesUrl(null);
|
||||
@@ -308,7 +309,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
// Setup our test object, to deny access
|
||||
filter = new MockAbstractProcessingFilter(false);
|
||||
filter.setFilterProcessesUrl("/j_mock_post");
|
||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||
filter.setFailureHandler(failureHandler);
|
||||
|
||||
// Test
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
@@ -468,7 +469,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
// Reject authentication, so exception would normally be stored in session
|
||||
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
|
||||
filter.setAllowSessionCreation(false);
|
||||
filter.setAuthenticationFailureUrl("/");
|
||||
filter.setFailureHandler(failureHandler);
|
||||
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
|
||||
filter.setSuccessHandler(successHandler);
|
||||
|
||||
@@ -509,8 +510,9 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
|
||||
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
|
||||
filter.setSuccessHandler(successHandler);
|
||||
filter.setAuthenticationFailureUrl("/error");
|
||||
filter.setServerSideRedirect(true);
|
||||
filter.setFailureHandler(failureHandler);
|
||||
failureHandler.setForwardToDestination(true);
|
||||
failureHandler.setDefaultFailureUrl("/error");
|
||||
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
|
||||
@@ -532,7 +534,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
filter.setSuccessHandler(successHandler);
|
||||
successHandler.setDefaultTargetUrl("http://monkeymachine.co.uk/");
|
||||
successHandler.setTargetUrlParameter("targetUrl");
|
||||
filter.setAuthenticationFailureUrl("/error");
|
||||
filter.setFailureHandler(failureHandler);
|
||||
|
||||
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||
|
||||
@@ -561,7 +563,7 @@ public class AbstractProcessingFilterTests extends TestCase {
|
||||
private MockAbstractProcessingFilter() {
|
||||
}
|
||||
|
||||
public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException {
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
if (grantAccess) {
|
||||
return new UsernamePasswordAuthenticationToken("test", "test", AuthorityUtils.createAuthorityList("TEST"));
|
||||
} else {
|
||||
|
||||
+1
-4
@@ -47,7 +47,6 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("loginFormUrl must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,7 +59,6 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("portMapper must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +71,6 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
ep.afterPropertiesSet();
|
||||
fail("Should have thrown IllegalArgumentException");
|
||||
} catch (IllegalArgumentException expected) {
|
||||
assertEquals("portResolver must be specified", expected.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +123,7 @@ public class AuthenticationProcessingFilterEntryPointTests extends TestCase {
|
||||
assertEquals("https://www.example.com:8443/bigWebApp/hello", response.getRedirectedUrl());
|
||||
|
||||
PortMapperImpl portMapper = new PortMapperImpl();
|
||||
Map map = new HashMap();
|
||||
Map<String,String> map = new HashMap<String,String>();
|
||||
map.put("8888", "9999");
|
||||
portMapper.setPortMappings(map);
|
||||
response = new MockHttpServletResponse();
|
||||
|
||||
+9
-7
@@ -24,8 +24,10 @@ import org.springframework.security.AuthenticationException;
|
||||
import org.springframework.security.ui.WebAuthenticationDetails;
|
||||
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
@@ -60,7 +62,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
filter.init(null);
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request);
|
||||
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
assertTrue(result != null);
|
||||
assertEquals("rod", request.getSession().getAttribute(
|
||||
AuthenticationProcessingFilter.SPRING_SECURITY_LAST_USERNAME_KEY));
|
||||
@@ -74,7 +76,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request);
|
||||
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
assertTrue(result != null);
|
||||
}
|
||||
|
||||
@@ -85,7 +87,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request);
|
||||
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
assertTrue(result != null);
|
||||
}
|
||||
|
||||
@@ -99,7 +101,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
request.addParameter("x", "rod");
|
||||
request.addParameter("y", "koala");
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request);
|
||||
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
assertTrue(result != null);
|
||||
assertEquals("127.0.0.1", ((WebAuthenticationDetails) result.getDetails()).getRemoteAddress());
|
||||
}
|
||||
@@ -112,7 +114,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
AuthenticationProcessingFilter filter = new AuthenticationProcessingFilter();
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
|
||||
Authentication result = filter.attemptAuthentication(request);
|
||||
Authentication result = filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
assertEquals("rod", result.getName());
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager(false));
|
||||
|
||||
try {
|
||||
filter.attemptAuthentication(request);
|
||||
filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
fail("Expected AuthenticationException");
|
||||
} catch (AuthenticationException e) {
|
||||
}
|
||||
@@ -143,7 +145,7 @@ public class AuthenticationProcessingFilterTests extends TestCase {
|
||||
filter.setAllowSessionCreation(false);
|
||||
filter.setAuthenticationManager(new MockAuthenticationManager(true));
|
||||
|
||||
filter.attemptAuthentication(request);
|
||||
filter.attemptAuthentication(request, new MockHttpServletResponse());
|
||||
|
||||
assertNull(request.getSession(false));
|
||||
}
|
||||
|
||||
+2
-1
@@ -3,6 +3,7 @@ package org.springframework.security.ui.webapp;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
@@ -38,7 +39,7 @@ public class DefaultLoginPageGeneratingFilterTests {
|
||||
private static class MockProcessingFilter extends AbstractProcessingFilter {
|
||||
|
||||
@Override
|
||||
public Authentication attemptAuthentication(HttpServletRequest request) throws AuthenticationException {
|
||||
public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@ http://www.springframework.org/schema/security http://www.springframework.org/sc
|
||||
<bean id="sif" class="org.springframework.security.context.HttpSessionContextIntegrationFilter"/>
|
||||
|
||||
<bean id="apf" class="org.springframework.security.ui.webapp.AuthenticationProcessingFilter">
|
||||
<property name="authenticationFailureUrl" value="/whocares2"/>
|
||||
<property name="authenticationManager">
|
||||
<bean class="org.springframework.security.MockAuthenticationManager"/>
|
||||
</property>
|
||||
|
||||
Reference in New Issue
Block a user