mirror of
https://github.com/spring-projects/spring-security.git
synced 2025-07-14 14:23:30 +00:00
ExceptionTranslationFilter does not handle committed responses
Fixes: gh-5273
This commit is contained in:
parent
f7f6798f71
commit
32f5fb5eb2
@ -131,6 +131,7 @@ class InterceptUrlConfigTests extends AbstractHttpConfigTests {
|
|||||||
when: 'user cannot access otheruser'
|
when: 'user cannot access otheruser'
|
||||||
request = new MockHttpServletRequest(method:'GET', servletPath : '/user/otheruser/abc')
|
request = new MockHttpServletRequest(method:'GET', servletPath : '/user/otheruser/abc')
|
||||||
login(request, 'user', 'password')
|
login(request, 'user', 'password')
|
||||||
|
response = new MockHttpServletResponse()
|
||||||
chain.reset()
|
chain.reset()
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'The response is OK'
|
then: 'The response is OK'
|
||||||
@ -138,6 +139,7 @@ class InterceptUrlConfigTests extends AbstractHttpConfigTests {
|
|||||||
when: 'user can access case insensitive URL'
|
when: 'user can access case insensitive URL'
|
||||||
request = new MockHttpServletRequest(method:'GET', servletPath : '/USER/user/abc')
|
request = new MockHttpServletRequest(method:'GET', servletPath : '/USER/user/abc')
|
||||||
login(request, 'user', 'password')
|
login(request, 'user', 'password')
|
||||||
|
response = new MockHttpServletResponse()
|
||||||
chain.reset()
|
chain.reset()
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'The response is OK'
|
then: 'The response is OK'
|
||||||
@ -164,6 +166,7 @@ class InterceptUrlConfigTests extends AbstractHttpConfigTests {
|
|||||||
when: 'user cannot access otheruser'
|
when: 'user cannot access otheruser'
|
||||||
request = new MockHttpServletRequest(method:'GET', servletPath : '/user/otheruser/abc')
|
request = new MockHttpServletRequest(method:'GET', servletPath : '/user/otheruser/abc')
|
||||||
login(request, 'user', 'password')
|
login(request, 'user', 'password')
|
||||||
|
response = new MockHttpServletResponse()
|
||||||
chain.reset()
|
chain.reset()
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'The response is OK'
|
then: 'The response is OK'
|
||||||
@ -171,6 +174,7 @@ class InterceptUrlConfigTests extends AbstractHttpConfigTests {
|
|||||||
when: 'user can access case insensitive URL'
|
when: 'user can access case insensitive URL'
|
||||||
request = new MockHttpServletRequest(method:'GET', servletPath : '/USER/user/abc')
|
request = new MockHttpServletRequest(method:'GET', servletPath : '/USER/user/abc')
|
||||||
login(request, 'user', 'password')
|
login(request, 'user', 'password')
|
||||||
|
response = new MockHttpServletResponse()
|
||||||
chain.reset()
|
chain.reset()
|
||||||
springSecurityFilterChain.doFilter(request,response,chain)
|
springSecurityFilterChain.doFilter(request,response,chain)
|
||||||
then: 'The response is OK'
|
then: 'The response is OK'
|
||||||
|
@ -135,6 +135,9 @@ public class ExceptionTranslationFilter extends GenericFilterBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (ase != null) {
|
if (ase != null) {
|
||||||
|
if (response.isCommitted()) {
|
||||||
|
throw new ServletException("Unable to handle the Spring Security Exception because the response is already committed.", ex);
|
||||||
|
}
|
||||||
handleSpringSecurityException(request, response, chain, ase);
|
handleSpringSecurityException(request, response, chain, ase);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -15,6 +15,23 @@
|
|||||||
*/
|
*/
|
||||||
package org.springframework.security.web.access;
|
package org.springframework.security.web.access;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||||
|
import static org.assertj.core.api.Assertions.fail;
|
||||||
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Mockito.doThrow;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.servlet.http.HttpSession;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@ -36,20 +53,6 @@ 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.SavedRequest;
|
import org.springframework.security.web.savedrequest.SavedRequest;
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
|
||||||
import javax.servlet.ServletException;
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.servlet.http.HttpSession;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.Locale;
|
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
|
||||||
import static org.assertj.core.api.Assertions.fail;
|
|
||||||
import static org.mockito.Matchers.any;
|
|
||||||
import static org.mockito.Mockito.doThrow;
|
|
||||||
import static org.mockito.Mockito.mock;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tests {@link ExceptionTranslationFilter}.
|
* Tests {@link ExceptionTranslationFilter}.
|
||||||
*
|
*
|
||||||
@ -302,7 +305,26 @@ public class ExceptionTranslationFilterTests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final AuthenticationEntryPoint mockEntryPoint = new AuthenticationEntryPoint() {
|
@Test
|
||||||
|
public void doFilterWhenResponseCommittedThenRethrowsException() throws Exception {
|
||||||
|
this.mockEntryPoint = mock(AuthenticationEntryPoint.class);
|
||||||
|
FilterChain chain = (request, response) -> {
|
||||||
|
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||||
|
httpResponse.sendError(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
throw new AccessDeniedException("Denied");
|
||||||
|
};
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
ExceptionTranslationFilter filter = new ExceptionTranslationFilter(mockEntryPoint);
|
||||||
|
|
||||||
|
assertThatThrownBy(() -> filter.doFilter(request, response, chain))
|
||||||
|
.isInstanceOf(ServletException.class)
|
||||||
|
.hasCauseInstanceOf(AccessDeniedException.class);
|
||||||
|
|
||||||
|
verifyZeroInteractions(mockEntryPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
private AuthenticationEntryPoint mockEntryPoint = new AuthenticationEntryPoint() {
|
||||||
public void commence(HttpServletRequest request, HttpServletResponse response,
|
public void commence(HttpServletRequest request, HttpServletResponse response,
|
||||||
AuthenticationException authException) throws IOException,
|
AuthenticationException authException) throws IOException,
|
||||||
ServletException {
|
ServletException {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user