Skip to content

Commit 1c4d6ed

Browse files
Consistently handle RequestRejectedException if it is wrapped
Closes gh-11645
1 parent efaee4e commit 1c4d6ed

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
@@ -41,6 +41,7 @@
4141
import org.springframework.security.web.firewall.RequestRejectedException;
4242
import org.springframework.security.web.firewall.RequestRejectedHandler;
4343
import org.springframework.security.web.firewall.StrictHttpFirewall;
44+
import org.springframework.security.web.util.ThrowableAnalyzer;
4445
import org.springframework.security.web.util.UrlUtils;
4546
import org.springframework.security.web.util.matcher.RequestMatcher;
4647
import org.springframework.util.Assert;
@@ -158,6 +159,8 @@ public class FilterChainProxy extends GenericFilterBean {
158159

159160
private RequestRejectedHandler requestRejectedHandler = new DefaultRequestRejectedHandler();
160161

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

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

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

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

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

0 commit comments

Comments
 (0)