Skip error page security filter for non-error dispatch type

Update `ErrorPageSecurityFilter` to defensively check that the
`DispatcherType` is `ERROR`. Although this check isn't necessary
for regular applications, it is needed if MockMvc is being used.

Fixes gh-28759
This commit is contained in:
Madhura Bhave 2021-11-22 20:16:25 -08:00 committed by Phillip Webb
parent 4eed637481
commit f621937d3b
2 changed files with 18 additions and 4 deletions

View File

@ -18,6 +18,7 @@ package org.springframework.boot.web.servlet.filter;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
@ -54,10 +55,12 @@ public class ErrorPageSecurityFilter extends HttpFilter {
@Override
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws IOException, ServletException {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!getPrivilegeEvaluator().isAllowed(request.getRequestURI(), authentication)) {
sendError(request, response);
return;
if (DispatcherType.ERROR.equals(request.getDispatcherType())) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (!getPrivilegeEvaluator().isAllowed(request.getRequestURI(), authentication)) {
sendError(request, response);
return;
}
}
chain.doFilter(request, response);
}

View File

@ -16,6 +16,7 @@
package org.springframework.boot.web.servlet.filter;
import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
@ -58,6 +59,7 @@ class ErrorPageSecurityFilterTests {
@BeforeEach
void setup() {
this.request.setDispatcherType(DispatcherType.ERROR);
given(this.context.getBean(WebInvocationPrivilegeEvaluator.class)).willReturn(this.privilegeEvaluator);
this.securityFilter = new ErrorPageSecurityFilter(this.context);
}
@ -95,4 +97,13 @@ class ErrorPageSecurityFilterTests {
verify(this.filterChain).doFilter(this.request, this.response);
}
@Test
void ignorePrivilegeEvaluationForNonErrorDispatchType() throws Exception {
this.request.setDispatcherType(DispatcherType.REQUEST);
given(this.privilegeEvaluator.isAllowed(anyString(), any())).willReturn(false);
this.securityFilter.doFilter(this.request, this.response, this.filterChain);
verifyNoInteractions(this.privilegeEvaluator);
verify(this.filterChain).doFilter(this.request, this.response);
}
}