Skip to content

Commit 24bb83e

Browse files
Consistently handle RequestRejectedException if it is wrapped
Closes gh-11645
1 parent 2e66b9f commit 24bb83e

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

web/src/main/java/org/springframework/security/web/FilterChainProxy.java

+12-2
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.springframework.security.web.firewall.RequestRejectedException;
4141
import org.springframework.security.web.firewall.RequestRejectedHandler;
4242
import org.springframework.security.web.firewall.StrictHttpFirewall;
43+
import org.springframework.security.web.util.ThrowableAnalyzer;
4344
import org.springframework.security.web.util.UrlUtils;
4445
import org.springframework.security.web.util.matcher.RequestMatcher;
4546
import org.springframework.util.Assert;
@@ -157,6 +158,8 @@ public class FilterChainProxy extends GenericFilterBean {
157158

158159
private RequestRejectedHandler requestRejectedHandler = new HttpStatusRequestRejectedHandler();
159160

161+
private ThrowableAnalyzer throwableAnalyzer = new ThrowableAnalyzer();
162+
160163
public FilterChainProxy() {
161164
}
162165

@@ -185,8 +188,15 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
185188
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
186189
doFilterInternal(request, response, chain);
187190
}
188-
catch (RequestRejectedException ex) {
189-
this.requestRejectedHandler.handle((HttpServletRequest) request, (HttpServletResponse) response, ex);
191+
catch (Exception ex) {
192+
Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(ex);
193+
Throwable requestRejectedException = this.throwableAnalyzer
194+
.getFirstThrowableOfType(RequestRejectedException.class, causeChain);
195+
if (!(requestRejectedException instanceof RequestRejectedException)) {
196+
throw ex;
197+
}
198+
this.requestRejectedHandler.handle((HttpServletRequest) request, (HttpServletResponse) response,
199+
(RequestRejectedException) requestRejectedException);
190200
}
191201
finally {
192202
this.securityContextHolderStrategy.clearContext();

web/src/test/java/org/springframework/security/web/FilterChainProxyTests.java

+15
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import static org.mockito.ArgumentMatchers.eq;
5050
import static org.mockito.BDDMockito.given;
5151
import static org.mockito.BDDMockito.willAnswer;
52+
import static org.mockito.BDDMockito.willThrow;
5253
import static org.mockito.Mockito.mock;
5354
import static org.mockito.Mockito.verify;
5455
import static org.mockito.Mockito.verifyZeroInteractions;
@@ -261,4 +262,18 @@ public void requestRejectedHandlerIsCalledIfFirewallThrowsRequestRejectedExcepti
261262
verify(rjh).handle(eq(this.request), eq(this.response), eq((requestRejectedException)));
262263
}
263264

265+
@Test
266+
public void requestRejectedHandlerIsCalledIfFirewallThrowsWrappedRequestRejectedException() throws Exception {
267+
HttpFirewall fw = mock(HttpFirewall.class);
268+
RequestRejectedHandler rjh = mock(RequestRejectedHandler.class);
269+
this.fcp.setFirewall(fw);
270+
this.fcp.setRequestRejectedHandler(rjh);
271+
RequestRejectedException requestRejectedException = new RequestRejectedException("Contains illegal chars");
272+
ServletException servletException = new ServletException(requestRejectedException);
273+
given(fw.getFirewalledRequest(this.request)).willReturn(mock(FirewalledRequest.class));
274+
willThrow(servletException).given(this.chain).doFilter(any(), any());
275+
this.fcp.doFilter(this.request, this.response, this.chain);
276+
verify(rjh).handle(eq(this.request), eq(this.response), eq((requestRejectedException)));
277+
}
278+
264279
}

0 commit comments

Comments
 (0)