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
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.
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
allow to configure ForwardHeaderFilter to 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 = {})
The text was updated successfully, but these errors were encountered:
FORCE_NONE is not a great name. NONE should simply do what the documentation claims it does: Ignore X-Forwarded-* headers.
What's required here is a new value like CLOUD_NATIVE which is much more self-explanatory.
I totally agree !
I wasn't sure what was the expected behavior of NONE, should it detect automatically cloud provider ? Or simply because we don't want to break backward compatibilIty.
But if that's ok to keep NONE and I troduce something more explicit I'm all for it.
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 theorg.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 isorg.springframework.boot.autoconfigure.web.ServerProperties.ForwardHeadersStrategy.NONE
, then the new code always tries to detect a cloud provider viaorg.springframework.boot.cloud.CloudPlatform.getActive(Environment)
(using the environment variables). In particular when Kubernetes is detected it configures theorg.apache.catalina.valves.RemoteIpValve
(which the same as ifserver.forward-headers-strategy
property was set toorg.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 theX-Forwarded-*
header. On the other hand switchingserver.forward-headers-strategy
toorg.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 theForwardedHeaderFilter
that has the same kind of side effect : this filter map allX-Forwarded-*
headers tojavax.servlet.ServletRequest
attributes but X-Forwarded-For.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
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
ForwardHeaderFilter
to not remove the headersOn another related topic, discovering this behavior and testing it (with unit test) was not straightforward. For example the code of
CloudPlatform
explicitly asks forStandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME
which obstructs the usual usage of the annotation@SpringBootTest(properties = {})
The text was updated successfully, but these errors were encountered: