Custom Spring Security firewall is lost when using spring-boot-cloudfoundry and Actuator in a reactive web application - #51549
Merged
Conversation
wilkinsona
requested changes
Sep 4, 2026
wilkinsona
left a comment
Member
There was a problem hiding this comment.
Thanks for the PR. I've left a couple of comments for your consideration.
aashikantkumar
force-pushed
the
gh-45377
branch
from
September 4, 2026 19:08
7db362b to
6c10166
Compare
Prior to this commit, CloudFoundryReactiveActuatorAutoConfiguration registered a BeanPostProcessor replaced the WebFilterChainProxy bean with one that handled CF security and delegated to the existing chain. Constructing a new WebFilterChainProxy resulted in the loss of any firewall customization on the existing chain as Spring Security does not provide an API to retreive the firewall from the existing chain and apply it to the new chain. This commit changes the approach and aligns it with its Servlet counterpart. Instead of post-processing the filter chain proxy, a new SecurityWebFilterChain that handles cloudfoundryapplication/** is defined. This chain becomes part of the existing WebFilterChainProxy, preserving any firewall customization. Signed-off-by: aashikantkumar <aashikantkumar2@gmail.com> See spring-projectsgh-51549
wilkinsona
added a commit
to aashikantkumar/spring-boot
that referenced
this pull request
Sep 8, 2026
…figuration" See spring-projectsgh-51549 Signed-off-by: Andy Wilkinson <andy.wilkinson@broadcom.com>
See spring-projectsgh-51549 Signed-off-by: Andy Wilkinson <andy.wilkinson@broadcom.com>
Member
|
Thanks very much, @aashikantkumar. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #45377
Hi team,
This PR addresses an issue where custom ServerWebExchangeFirewall configurations are lost when running reactive applications on Cloud Foundry.
What was happening?
When VCAP_APPLICATION is present, CloudFoundryReactiveActuatorAutoConfiguration used a BeanPostProcessor (WebFilterChainPostProcessor) to wrap WebFilterChainProxy.
The trouble with that approach is that instantiating a new WebFilterChainProxy creates a fresh instance with its private firewall field defaulting to new StrictServerWebExchangeFirewall(). As a result:
Any custom ServerWebExchangeFirewall bean declared by the user was discarded.
Direct customizations (e.g. calling setFirewall(...) on the proxy) were also lost.
Incoming requests were evaluated by the new proxy's strict firewall at the perimeter, rejecting valid requests that rely on customized firewall rules (like matrix parameters or specific URI encodings).
The Fix
Following @wilkinsona's suggestion in #45377, we aligned the reactive configuration with how the servlet side already handles this in IgnoredCloudFoundryPathsWebSecurityConfiguration:
Removed WebFilterChainPostProcessor.
Added a dedicated @order(-1) SecurityWebFilterChain bean matching /cloudfoundryapplication/** with permitAll(), csrf.disable(), and CORS configuration.
This allows Spring Security's native ServerHttpSecurityConfiguration to create and keep the single WebFilterChainProxy. Cloud Foundry routes are given higher precedence to bypass authentication, while the rest of the application's security configuration and the user's custom firewall remain completely untouched.
How this was verified
Added regression tests in CloudFoundryReactiveActuatorAutoConfigurationTests:
customFirewallBeanIsPreserved: Asserts that a custom ServerWebExchangeFirewall @bean stays on WebFilterChainProxy.
directlyConfiguredFirewallIsPreserved: Asserts that firewalls set directly via proxy.setFirewall(...) in a post-processor survive.
customFirewallIsInvokedOnRequests: Verifies runtime execution of firewall.getFirewalledExchange(...).
userSecurityWebFilterChainIsPreserved: Confirms that user-defined SecurityWebFilterChain beans coexist alongside the Cloud Foundry chain with correct ordering.
Ran:
bash
./gradlew :module:spring-boot-cloudfoundry:test
./gradlew :module:spring-boot-cloudfoundry:check
All reactive tests, servlet tests, checkstyle, and Spring JavaFormat checks pass cleanly.
Contributor Checklist
Signed-off-by trailer included in commit for DCO
Code formatted with Spring JavaFormat
Checkstyle checks pass
@author tag added
Unit/slice regression tests added