Skip to content

Commit 6a2ca52

Browse files
Consistently handle RequestRejectedException if it is wrapped
Closes gh-11645
1 parent 269c711 commit 6a2ca52

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;
@@ -154,6 +155,8 @@ public class FilterChainProxy extends GenericFilterBean {
154155

155156
private RequestRejectedHandler requestRejectedHandler = new DefaultRequestRejectedHandler();
156157

158+
private ThrowableAnalyzer throwableAnalyzer = new ThrowableAnalyzer();
159+
157160
public FilterChainProxy() {
158161
}
159162

@@ -182,8 +185,15 @@ public void doFilter(ServletRequest request, ServletResponse response, FilterCha
182185
request.setAttribute(FILTER_APPLIED, Boolean.TRUE);
183186
doFilterInternal(request, response, chain);
184187
}
185-
catch (RequestRejectedException ex) {
186-
this.requestRejectedHandler.handle((HttpServletRequest) request, (HttpServletResponse) response, ex);
188+
catch (Exception ex) {
189+
Throwable[] causeChain = this.throwableAnalyzer.determineCauseChain(ex);
190+
Throwable requestRejectedException = this.throwableAnalyzer
191+
.getFirstThrowableOfType(RequestRejectedException.class, causeChain);
192+
if (!(requestRejectedException instanceof RequestRejectedException)) {
193+
throw ex;
194+
}
195+
this.requestRejectedHandler.handle((HttpServletRequest) request, (HttpServletResponse) response,
196+
(RequestRejectedException) requestRejectedException);
187197
}
188198
finally {
189199
SecurityContextHolder.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;
@@ -252,4 +253,18 @@ public void requestRejectedHandlerIsCalledIfFirewallThrowsRequestRejectedExcepti
252253
verify(rjh).handle(eq(this.request), eq(this.response), eq((requestRejectedException)));
253254
}
254255

256+
@Test
257+
public void requestRejectedHandlerIsCalledIfFirewallThrowsWrappedRequestRejectedException() throws Exception {
258+
HttpFirewall fw = mock(HttpFirewall.class);
259+
RequestRejectedHandler rjh = mock(RequestRejectedHandler.class);
260+
this.fcp.setFirewall(fw);
261+
this.fcp.setRequestRejectedHandler(rjh);
262+
RequestRejectedException requestRejectedException = new RequestRejectedException("Contains illegal chars");
263+
ServletException servletException = new ServletException(requestRejectedException);
264+
given(fw.getFirewalledRequest(this.request)).willReturn(mock(FirewalledRequest.class));
265+
willThrow(servletException).given(this.chain).doFilter(any(), any());
266+
this.fcp.doFilter(this.request, this.response, this.chain);
267+
verify(rjh).handle(eq(this.request), eq(this.response), eq((requestRejectedException)));
268+
}
269+
255270
}

0 commit comments

Comments
 (0)