mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-12 13:23:29 +00:00
SEC-462: 302 redirect is not usable for SOAP clients
http://jira.springframework.org/browse/SEC-462
This commit is contained in:
parent
5e27b326d2
commit
439b0be58e
@ -210,13 +210,15 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
|||||||
private boolean migrateInvalidatedSessionAttributes = true;
|
private boolean migrateInvalidatedSessionAttributes = true;
|
||||||
|
|
||||||
private boolean allowSessionCreation = true;
|
private boolean allowSessionCreation = true;
|
||||||
|
|
||||||
|
private boolean serverSideRedirect = false;
|
||||||
|
|
||||||
//~ Methods ========================================================================================================
|
//~ Methods ========================================================================================================
|
||||||
|
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
|
Assert.hasLength(filterProcessesUrl, "filterProcessesUrl must be specified");
|
||||||
Assert.hasLength(defaultTargetUrl, "defaultTargetUrl must be specified");
|
Assert.hasLength(defaultTargetUrl, "defaultTargetUrl must be specified");
|
||||||
Assert.hasLength(authenticationFailureUrl, "authenticationFailureUrl must be specified");
|
// Assert.hasLength(authenticationFailureUrl, "authenticationFailureUrl must be specified");
|
||||||
Assert.notNull(authenticationManager, "authenticationManager must be specified");
|
Assert.notNull(authenticationManager, "authenticationManager must be specified");
|
||||||
Assert.notNull(rememberMeServices, "rememberMeServices cannot be null");
|
Assert.notNull(rememberMeServices, "rememberMeServices cannot be null");
|
||||||
Assert.notNull(targetUrlResolver, "targetUrlResolver cannot be null");
|
Assert.notNull(targetUrlResolver, "targetUrlResolver cannot be null");
|
||||||
@ -343,7 +345,7 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||||
Authentication authResult) throws IOException {
|
Authentication authResult) throws IOException, ServletException {
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Authentication success: " + authResult.toString());
|
logger.debug("Authentication success: " + authResult.toString());
|
||||||
}
|
}
|
||||||
@ -437,7 +439,7 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response,
|
||||||
AuthenticationException failed) throws IOException {
|
AuthenticationException failed) throws IOException, ServletException {
|
||||||
SecurityContextHolder.getContext().setAuthentication(null);
|
SecurityContextHolder.getContext().setAuthentication(null);
|
||||||
|
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
@ -463,8 +465,14 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
|||||||
onUnsuccessfulAuthentication(request, response, failed);
|
onUnsuccessfulAuthentication(request, response, failed);
|
||||||
|
|
||||||
rememberMeServices.loginFail(request, response);
|
rememberMeServices.loginFail(request, response);
|
||||||
|
|
||||||
sendRedirect(request, response, failureUrl);
|
if (failureUrl == null) {
|
||||||
|
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Authentication Failed:" + failed.getMessage());
|
||||||
|
} else if (serverSideRedirect){
|
||||||
|
request.getRequestDispatcher(failureUrl).forward(request, response);
|
||||||
|
} else {
|
||||||
|
sendRedirect(request, response, failureUrl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String determineFailureUrl(HttpServletRequest request, AuthenticationException failed) {
|
protected String determineFailureUrl(HttpServletRequest request, AuthenticationException failed) {
|
||||||
@ -601,4 +609,13 @@ public abstract class AbstractProcessingFilter extends SpringSecurityFilter impl
|
|||||||
public void setTargetUrlResolver(TargetUrlResolver targetUrlResolver) {
|
public void setTargetUrlResolver(TargetUrlResolver targetUrlResolver) {
|
||||||
this.targetUrlResolver = targetUrlResolver;
|
this.targetUrlResolver = targetUrlResolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -293,20 +293,6 @@ public class AbstractProcessingFilterTests extends TestCase {
|
|||||||
assertEquals(sessionPreAuth, request.getSession());
|
assertEquals(sessionPreAuth, request.getSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testStartupDetectsInvalidAuthenticationFailureUrl() throws Exception {
|
|
||||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
|
||||||
filter.setAuthenticationManager(new MockAuthenticationManager());
|
|
||||||
filter.setDefaultTargetUrl("/");
|
|
||||||
filter.setFilterProcessesUrl("/j_spring_security_check");
|
|
||||||
|
|
||||||
try {
|
|
||||||
filter.afterPropertiesSet();
|
|
||||||
fail("Should have thrown IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException expected) {
|
|
||||||
assertEquals("authenticationFailureUrl must be specified", expected.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testStartupDetectsInvalidAuthenticationManager() throws Exception {
|
public void testStartupDetectsInvalidAuthenticationManager() throws Exception {
|
||||||
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
AbstractProcessingFilter filter = new MockAbstractProcessingFilter();
|
||||||
filter.setAuthenticationFailureUrl("/failed.jsp");
|
filter.setAuthenticationFailureUrl("/failed.jsp");
|
||||||
@ -547,6 +533,45 @@ public class AbstractProcessingFilterTests extends TestCase {
|
|||||||
assertNull(request.getSession(false));
|
assertNull(request.getSession(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SEC-462
|
||||||
|
*/
|
||||||
|
public void testLoginErrorWithNoFailureUrlSendsUnauthorizedStatus() throws Exception {
|
||||||
|
MockHttpServletRequest request = createMockRequest();
|
||||||
|
|
||||||
|
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||||
|
MockFilterChain chain = new MockFilterChain(true);
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
|
||||||
|
filter.setDefaultTargetUrl("http://monkeymachine.co.uk/");
|
||||||
|
|
||||||
|
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||||
|
|
||||||
|
assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SEC-462
|
||||||
|
*/
|
||||||
|
public void testServerSideRedirectForwardsToFailureUrl() throws Exception {
|
||||||
|
MockHttpServletRequest request = createMockRequest();
|
||||||
|
|
||||||
|
MockFilterConfig config = new MockFilterConfig(null, null);
|
||||||
|
MockFilterChain chain = new MockFilterChain(true);
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
MockAbstractProcessingFilter filter = new MockAbstractProcessingFilter(false);
|
||||||
|
filter.setDefaultTargetUrl("http://monkeymachine.co.uk/");
|
||||||
|
filter.setAuthenticationFailureUrl("/error");
|
||||||
|
filter.setServerSideRedirect(true);
|
||||||
|
|
||||||
|
executeFilterInContainerSimulator(config, filter, request, response, chain);
|
||||||
|
|
||||||
|
assertEquals("/error", response.getForwardedUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//~ Inner Classes ==================================================================================================
|
//~ Inner Classes ==================================================================================================
|
||||||
|
|
||||||
private class MockAbstractProcessingFilter extends AbstractProcessingFilter {
|
private class MockAbstractProcessingFilter extends AbstractProcessingFilter {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user