After seeing discussion put in #18949,
Let's see the following case
Spring boot BOM version 2.5.6 Spring cloud 2020.0.4
- spring gateway with default locator configuration exposed on http://my-gateway.url
- a spring boot application with a
server.servlet.context-path
set tomy-local-context-path
and seen by first application asapp-ui
in its discovery client
The second application uses thymeleaf @{/js/script.js}
in the template returned by the handler of /some-mvc-controller
When accessing on http://my-gateway.url/app-ui/my-local-context-path/some-mvc-controller
- spring cloud gateway calls app-ui application on
/my-local-context-path/some-mvc-controller
withX-Forwarded-Prefix
set to/app-ui
ForwardedHeaderFilter
replaces http servlet request context path to/app-ui
, request uri to/app-ui/some-mvc-controller
- Thymeleaf resolves js url to
http://my-gateway.url/app-ui/js/script.js
that ends in404
error as the correct url should have beenhttp://my-gateway.url/app-ui/my-local-context-path/js/script.js
Unless I missed something, I think that it is sad that, using all default behaviour of spring tools (but context-path) is not possible.
I would like to provide a way to let application choose between a policy of REPLACEMENT
or PREPEND
. If none, something like setting inner classes of ForwardedHeaderFilter
as protected
instead of private
in order to let application easily implement its own policy.
Before going directly to a pull request, I prefer discussing whether you're ok with that and which would be the prefered solution
- moving inner classes to
protected
without any other change - allowing to switch between replacement and prepend based on
server.framework-forward-header-policy
valued toREPLACEMENT
by default
Comment From: antechrestos
A workaround is the following filter put just after ForwardedHeaderFilter
in the chain
Comment From: rstoyanchev
From the previous threads, it sounds like the expected approach is to not expose the contextPath of the app behind the proxy to external clients. So the incoming URL is http://my-gateway.url/app-ui/some-mvc-controller
and the gateway forwards to /my-local-context-path/some-mvc-controller
with X-Forwarded-Prefix set to /app-ui
.
Comment From: antechrestos
@rstoyanchev yes I understood the approach; yet I am facing a scenario not pleasant:
- a legacy exposing both ui and api under the context path
- connected to system not imperatively going through the reverse proxy, ie knowing ui/api address with local context path
- a ui allowing users to access to proxified ui/swagger
Hence in this scenario, using the default locator configuration of spring cloud gateway , resolution of ressource url by proxified thymeleaf fails.
I have a solution based on a home made solution, yet I am not very pleased implementing framework bypass.I would rather
- either override framework filter, by being allowed to extend inner classes (moving them from
private
toprotected
, or providing a pattern allowing to modify the context path replacement behaviour) - provide a configuration based way of switching behaviour
My point is that it is sad to have a restrictive behaviour on a border component.
Comment From: rstoyanchev
I get that you're in this scenario, and thanks for the extra detail, but the previous issue is more than 5 years old, so this doesn't seem to be very common. Taking a look at ForwardedPrefixExtractor
and thinking about making that open for extension or configurable, I think the filter you've come up with seems a more straight-forward alternative to me.
Comment From: rstoyanchev
Closing for now but can re-open if there is more demand.