You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Introduce a configurable web-captor.defer-outer-filter-packages property (defaulting to org.springframework.security.) so exceptions from configured package prefixes are re-thrown to outer servlet filters instead of rendered as 500s. Pass the configured list from WebCaptorProperties through AppConfig into UnhandledExceptionResponseFilter, replace reflection-based Spring Security checks with a generic cause-chain prefix check (shouldDeferToOuterFilter), and update logging. Add README documentation for the new property and comprehensive tests (unit updates, new integration test and test fixture com.acme.security.CustomDenied) to verify configurable deferral behavior.
Copy file name to clipboardExpand all lines: README.md
+48Lines changed: 48 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -80,6 +80,7 @@ All properties are optional. The library works out of the box with sensible defa
80
80
| Property | Type | Default | Description |
81
81
|---|---|---|---|
82
82
|`web-captor.enabled`|`boolean`|`true`| Enable or disable all HTTP capturing |
83
+
|`web-captor.defer-outer-filter-packages`|`List<String>`|`[org.springframework.security.]`| Package prefixes whose exceptions are re-thrown for an outer servlet filter to translate. See [Defer Outer-Filter Packages](#defer-outer-filter-packages-web-captordefer-outer-filter-packages). |
Copy file name to clipboardExpand all lines: spring-web-captor/src/main/java/com/davidrandoll/spring_web_captor/publisher/response/UnhandledExceptionResponseFilter.java
+34-62Lines changed: 34 additions & 62 deletions
Original file line number
Diff line number
Diff line change
@@ -15,69 +15,44 @@
15
15
16
16
importjava.io.IOException;
17
17
importjava.util.HashMap;
18
+
importjava.util.List;
18
19
19
20
/**
20
-
* Last-resort fallback that renders a JSON 500 body for exceptions that escape
21
-
* <em>every</em> other layer of the request pipeline.
21
+
* Safety-net renderer for runtime exceptions that escape <em>everything</em> — no
22
+
* {@code HandlerExceptionResolver} claimed them inside the dispatcher, no servlet filter
23
+
* outside the dispatcher (e.g. Spring Security's {@code ExceptionTranslationFilter})
24
+
* translated them via {@code sendError}, and there is no Spring Boot {@code /error}
25
+
* endpoint that would render them on an error dispatch.
22
26
*
23
-
* <p>Why we still need a security-exception skip here: depending on how Spring Security 6's
24
-
* {@code CompositeFilterChainProxy} composes the host application's servlet filters, this
25
-
* filter can end up <em>inside</em> {@code ExceptionTranslationFilter}'s call to
26
-
* {@code chain.doFilter}. In that configuration, an {@code AccessDeniedException} bubbling up
27
-
* from the dispatcher reaches us <em>before</em> {@code ExceptionTranslationFilter} can
28
-
* translate it to a 403/401. We detect that situation structurally — by checking whether the
29
-
* escaped exception (or any cause in its chain) is a Spring Security exception — and
30
-
* <em>re-throw</em> it so the outer security filter can do its job.
31
-
*
32
-
* <p>Detection uses a <strong>package prefix</strong> (any class in
33
-
* {@code org.springframework.security.*}), not a hard-coded class list, so new Spring Security
34
-
* exception subclasses in future versions are handled automatically — no maintenance required.
35
-
*
36
-
* <p>For every other unhandled {@code RuntimeException} we render the captor's standard 500 body.
37
-
* If a response is already committed when an exception escapes, we re-raise rather than try to
38
-
* write a new body — the client gets whatever the container's error handling produces (never
39
-
* an empty response).
27
+
* <p>Exceptions whose class lives in any package listed in
28
+
* {@code web-captor.defer-outer-filter-packages} (default: Spring Security) are re-thrown
29
+
* instead of being rendered, so the outer translator can run. To extend for another framework
30
+
* with the same outer-filter-translates-via-sendError pattern, just add its root package to
31
+
* the property — no code change to the library needed.
0 commit comments