Skip to content

ForwardedHeaderFilter should allow prepend / replace depending on configuration #27739

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
antechrestos opened this issue Nov 27, 2021 · 5 comments
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply

Comments

@antechrestos
Copy link

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 to my-local-context-path and seen by first application as app-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 with X-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 in 404 error as the correct url should have been http://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 to REPLACEMENT by default
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 27, 2021
@antechrestos
Copy link
Author

A workaround is the following filter put just after ForwardedHeaderFilter in the chain

@rstoyanchev rstoyanchev added the in: web Issues in web modules (web, webmvc, webflux, websocket) label Nov 29, 2021
@rstoyanchev
Copy link
Contributor

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.

@rstoyanchev rstoyanchev added the status: waiting-for-feedback We need additional information before we can continue label Nov 29, 2021
@antechrestos
Copy link
Author

@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 to protected, 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.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Nov 29, 2021
@rstoyanchev
Copy link
Contributor

rstoyanchev commented Nov 30, 2021

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.

@rstoyanchev
Copy link
Contributor

Closing for now but can re-open if there is more demand.

@rstoyanchev rstoyanchev added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged or decided on status: feedback-provided Feedback has been provided labels Dec 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: web Issues in web modules (web, webmvc, webflux, websocket) status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

No branches or pull requests

3 participants