SEC-2027: Invoke SecurityContextHolder.clearContext() only on outer invocation of FilterChainProxy
When SEC-1950 was introduced it caused problems when a <filter-mapping> was mapped to multiple dispatchers (i.e. REQUEST and FORWARD) since when the second dispatcher completed execution it cleared the SecurityContext and the original FilterChain would then save the cleared out SecurityContext. We now use a pattern similar to the OncePerRequestFilter to only invoke SecurityContextHolder.clearContext() on the first invocation of the Filter. We do not simply extend OncePerRequestFilter because we want to invoke the delegate filters for every request.
This commit is contained in:
@@ -196,4 +196,31 @@ public class FilterChainProxyTests {
|
||||
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
|
||||
// SEC-2027
|
||||
@Test
|
||||
public void doFilterClearsSecurityContextHolderOnceOnForwards() throws Exception {
|
||||
final FilterChain innerChain = mock(FilterChain.class);
|
||||
when(matcher.matches(any(HttpServletRequest.class))).thenReturn(true);
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock inv) throws Throwable {
|
||||
TestingAuthenticationToken expected = new TestingAuthenticationToken("username", "password");
|
||||
SecurityContextHolder.getContext().setAuthentication(expected);
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock inv) throws Throwable {
|
||||
innerChain.doFilter(request, response);
|
||||
return null;
|
||||
}
|
||||
}).when(filter).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class), any(FilterChain.class));;
|
||||
fcp.doFilter(request, response, innerChain);
|
||||
assertSame(expected, SecurityContextHolder.getContext().getAuthentication());
|
||||
return null;
|
||||
}
|
||||
}).when(filter).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class), any(FilterChain.class));
|
||||
|
||||
fcp.doFilter(request, response, chain);
|
||||
|
||||
verify(innerChain).doFilter(any(HttpServletRequest.class), any(HttpServletResponse.class));
|
||||
assertNull(SecurityContextHolder.getContext().getAuthentication());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user