-
Notifications
You must be signed in to change notification settings - Fork 41.6k
Description
I'm working on applications that requires access to X-Forwarded-* headers, unfortunately Spring Boot 2.2 changed the way it auto-configures itself, and those are not anymore available in the custom code unless you dive in to understand the change.
In spring boot 2.1 when the server.use-forward-headers property was not set, Spring Boot did not configure the org.apache.catalina.valves.RemoteIpValve from Tomcat when the application was running within a cloud provider environment.
This changed in Spring Boot 2.2, when the new property server.forward-headers-strategy is not configured, i.e. it's value is org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy.NONE, then the new code always tries to detect a cloud provider via org.springframework.boot.cloud.CloudPlatform.getActive(Environment) (using the environment variables). In particular when Kubernetes is detected it configures the org.apache.catalina.valves.RemoteIpValve (which the same as if server.forward-headers-strategy property was set to org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy.NATIVE).
This Tomcat Valve has a side effect : this class replaces the value in the corresponding attribute of javax.servlet.ServletRequest and removes the X-Forwarded-* header. On the other hand switching server.forward-headers-strategy to org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy.FRAMEWORK to prevent the auto-detection of the cloud platform does not help as well. This time it's the ForwardedHeaderFilter that has the same kind of side effect : this filter map all X-Forwarded-* headers to javax.servlet.ServletRequest attributes but X-Forwarded-For.
- Filters forward headers
- customize tomcat behind a proxy server
- deprecations-in-spring-boot-22
- Add 'server.remove-forward-headers' options #11525
- Add support for X-Forwarded-Host using Tomcat's new RemoteIpValve hostHeader attribute #18233
This is unfortunate as this isn't explicitly documented, and there's no way to disable this behavior by configuration. While I understand the value of the change as a whole, I believe this particular scenario could be seen as a regression that was introduced.
Currently the only hack to prevent this is to register a dummy of ForwardHeaderFilter
@Bean
public ForwardedHeaderFilter disabledForwardedHeaderFilter() {
return new ForwardedHeaderFilter() {
@Override
protected boolean shouldNotFilter(HttpServletRequest request) {
return true;
}
};
}
What I think is missing in the current code 2.2.1.RELEASE are these things
org.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy.FORCE_NONE- allow to configure
ForwardHeaderFilterto not remove the headers
On another related topic, discovering this behavior and testing it (with unit test) was not straightforward. For example the code of CloudPlatform explicitly asks for StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME which obstructs the usual usage of the annotation @SpringBootTest(properties = {})