traefik / traefik

The Cloud Native Application Proxy
https://traefik.io
MIT License
49.12k stars 4.93k forks source link

Get traefik to send the name of the frontend of the receiving request via http headers to the forward auth backend #3919

Open dniel opened 5 years ago

dniel commented 5 years ago

Do you want to request a feature or report a bug?

Feature

What did you expect to see?

Hi, I'm implementing an forwardauth backend webapp to authenticate users with forward authentication and oauth.

Is it possible to get traefik to send the name of the frontend of the receiving request via http headers to the forward auth backend when I have configured the forward auth on the entrypoint?

If possible, then I could put the common forward auth configuration in traefik on the entrypoint, and add configuration per frontend into a config file for my backend to configure different kinds of parameters for authentication, like clientid and client secret for each frontend, but still have a common auth forward config on the entrypoint.

The other possibility I see is to put the forward auth config in traefik on every frontend, and put a query param or custom header with the name of the frontend to the forward auth backend call. unfortunately this would mean that every frontend configured would need the forward auth configration with alot of duplication of code, and if someone forgets to add the config to the frontend its by default open.

It would be more secure if I could put a common forward auth security config on the entrypoint and then add specific rules and parameters of authentication based on from which frontend in my own forward auth backend, but to do that I need to know which traefik frontend the request is associated with and sent to my forward auth webapp to select the correct configuration for that specific frontend

dniel commented 5 years ago

I cant figure out a way to specify which frontend that tries to use the backend. The backend needs to know which frontend that tries to authenticate so that backend can apply different parameters to the authentication per. frontend. The only way to specify from which frontend I have found is to add a customrequestheader, but that must be done by adding config for every frontend.

And when adding forwardauth config to the entrypoint, no config is per frontend is sent at all to the forward-auth backend, which makes it suitable for just a single way of authenticating with a set of static params to use.

Could possible use the forwarded host header to try to figure out which frontend that sent the authentication request to the forwardauth backend, but that does not work when multiple frontends use the same hostname but different paths.

But the best way would be a header like x-forwarded-frontend with the name, and even better if that header would be added even if the forward-auth config is added to the entrypoint.

ldez commented 5 years ago

after some discussion on Slack with @dniel, from my understanding, a sort of "middleware" that add some extra information (like router, provider, etc..) can be an answer to this issue.

llacroix commented 4 years ago

@dniel One solution to this problem thought, not the solution I really like but as I could see, when setting the global url, the auth server is itself behind a proxy. This cause a few headers to be overridden by traefik. X-Forwarded-Host being one of them. This in return cause the issue you have.

The solution I have in mind that requires no development is to put a second proxy between traefik and traefik. In other words the request goes like this usually:

traefik -> example.com
traefik -> forward host auth.example.com
<- client

By adding frontend proxy other than traefik you can do something like this:

proxy -> traefik -> example.com
proxy (rewrite headers) -> traefik -> forward auth.example.com
<- client

The main difference is that by setting a frontend proxy, you can always rewrite the headers to keep the existing forwarded headers even for the auth request.

The downside is that it makes the request path a bit longer than necessary.

ldez commented 4 years ago

Take a look at https://docs.traefik.io/v2.0/routing/entrypoints/#forwarded-header

branchmispredictor commented 4 years ago

Have there been any updates here? I can see it being pretty useful to forward the frontend or route info to a forward auth backend to allow for more integrated configuration and control.

dniel commented 4 years ago

Update since first reported this issue one and a half year ago, I still think it could be valuable to have some meta-info about the router that matched the request when doing for example forward authentication to avoid complex logic in the forwardauth endpoint. If I could get the name of the receiving router as input to the forwardauth endpoint I would need very little logic to apply the correct authentication and authorization logic and by reusing the result of the route matching rules in traefik I could do even more complex authz + authn in the backend without needing to do my own mapping rules. It would help me a lot.