oauth2-proxy: Not redirecting to subpath after login using Traefik's 401 errors middleware
Expected Behavior
- Attempt to access service on subpath example.domain/sub/path
- Get redirected to oauth2-proxy on example.domain/oauth2/auth
- Log in through auth provider
- Get redirected to example.domain/sub/path
Current Behavior
- Attempt to access service on subpath example.domain/sub/path
- Get redirected to oauth2-proxy on example.domain/oauth2/auth
- Log in through auth provider
- Get redirected to example.domain instead of example.domain/sub/path
Steps to Reproduce (for bugs)
- Use following config values for oauth2-proxy
oauth2_proxy.cfg: |-
provider = "oidc"
provider_display_name = "Keycloak"
redirect_url = "https://example.domain/oauth2/callback"
oidc_issuer_url = "https://example.domain/auth/"
cookie_secure = false
reverse_proxy = true
email_domains = [ "*" ]
upstreams = [ "file:///dev/null" ]
pass_access_token = true
pass_authorization_header = true
set_authorization_header = true
set_xauthrequest = true
pass_user_headers = true
whitelist_domains= [ ".example.domain" ]
- Set up traefik middlewares and ingresses as currently described in the docs: https://oauth2-proxy.github.io/oauth2-proxy/docs/configuration/overview#forwardauth-with-401-errors-middleware In kubernetes CRD form:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: auth-headers
spec:
headers:
sslRedirect: true
stsSeconds: 315360000
browserXssFilter: true
contentTypeNosniff: true
forceSTSHeader: true
stsIncludeSubdomains: true
stsPreload: true
frameDeny: true
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: oauth-auth
spec:
forwardAuth:
address: https://example.domain/oauth2/auth
trustForwardHeader: true
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: oauth-errors
spec:
errors:
status:
- "401-403"
service:
name: oauth2-proxy
port: 80
query: "/oauth2/sign_in"
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: oauth2-proxy
spec:
entryPoints:
- websecure
routes:
- match: PathPrefix(`/oauth2/`)
kind: Rule
services:
- name: oauth2-proxy
port: 80
middlewares:
- name: auth-headers
- Expose a service
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: subpath-test
spec:
entryPoints:
- websecure
routes:
- match: PathPrefix(`/foo/bar`)
kind: Rule
services:
- name: bar
port: 8080
middlewares:
- name: oauth-errors
namespace: traefik-v2
- name: oauth-auth
namespace: traefik-v2
- Navigate to example.domain/foo/bar, follow login flow
Context
There seem to be quite a few issues related to Oauth2 Proxy and Traefik, however the closest I could find to my current issue is https://github.com/oauth2-proxy/oauth2-proxy/issues/397 which is over a year old. Besides the environment traefik is running in, the issue is very similar. https://github.com/oauth2-proxy/oauth2-proxy/issues/1255 seems somewhat similar as well, but I’m currently not using skip-provider-button.
As there are several issues related to Traefik + Oauth2 Proxy both here and on Traefik’s github page, I might have missed potential solutions, but from what I’ve read so far it seems like the only workaround at the moment is to create a middleware that attaches the X-Auth-Request-Redirect header manually. As Traefik is currently not offering dynamic headers, this has to be done per service. Both https://github.com/oauth2-proxy/oauth2-proxy/issues/397 and https://github.com/oauth2-proxy/oauth2-proxy/issues/46#issuecomment-687155032 seem to use custom middlewares for each service to solve the issue, which is far from ideal.
https://github.com/traefik/traefik/issues/6839 might eventually provide a generic solution from Traefik’s site, although I’m not completely sure if this is a surefire fix.
An attempt was made at providing the correct functionality from Traefik’s side: https://github.com/traefik/traefik/pull/6835 however developers did not like the oauth2-proxy specific approach.
I’ve posted this here as oauth2-proxy seems more inclined to adopt Traefik specific fixes than the other way around.
Your Environment
- Version used: oauth-proxy2 v7.1.3 traefik v2.4.9 kubernetes v1.20
Multiple services are hosted on the same domain, but under different subpaths.
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Reactions: 6
- Comments: 43 (11 by maintainers)
My team ran into a similar issue and tried solutions from here. I’m leaving my solution here for others who end up here too:
/oauth2/*endpoints we just use/for forward auth. As the documentation states:--upstream static://204.--skip-provider-button.Now traefik will do forward auth against
/and when the user is unauthenticated we get an immediate redirect. If the user is authenticated the proxy responds with 204 and traefik will call the real service for the site.This is kinda obvious if you read the documentation carefully. The
oauth2/authis really only suitable for nginx and I think this how my team ended up here.Hope that helps.
I am using the hack above for now, i.e using a custom template for sign_in where I set rd=window.location. I copied the template files from https://github.com/oauth2-proxy/oauth2-proxy/tree/master/pkg/app/pagewriter, configure them with
and just added
You need to correctly configure WHITELIST_DOMAINS as well. This makes all my subdomains work with the same oauth2-proxy callback.
I’m haven’t taken the time to figure out how to set the Redirect parameter correctly, but hopefully someone will shed the light on that eventually 😃
I’ve posted the issue over at Traefik’s forum, but looking at the lack of response on similar issues over there, I don’t exactly have high hopes for a meaningful reply.
Earlier in the thread you said the following:
Do you have any clue on which component provides the rd parameter, i.e. is it Traefik, Oauth2-proxy, or something entirely different?
In the logs from my working traefik-forward-auth setup, a proxy auth component created specifically for Traefik, I can see my original url being sent as part of the state from the forward auth component to Keycloak (our OIDC provider) and then again in the callback. These are the logs for a request to
sub.domain.com/monitoring/prometheus/graph:On their github page, the following is mentioned:
I’m guessing this is what does not work with Oauth2-proxy? Where traefik-forward-auth provides the redirect url themselves, oauth2-proxy expects Traefik to provide the redirect url?
You also said:
I did a quick search for ‘traefik check’ in the code, but couldn’t find anything relevant. Can you clarify what these checks are or point me in the right direction to find these checks?
Thanks for all the help you’ve provided so far.
This hack could be done in the OAUTH2_PROXY_FOOTER environnement variable like :
The project refers to OAuth2 Proxy yes. This project has been a passion project for a long time, we still want to maintain it and provide guidance where we can but we can only do so when our schedules permit it. Typically my evenings and weekends I try to spend some time on the project but I can’t as often as I would like and I don’t get to do much on the code side anymore either.
I’m not sure about alternatives no. The real solution is to bring in some new maintainers but finding people willing and able to be a maintainer is difficult.
@JoelSpeed please excuse my slightly off-topic question, but does “the project” refer to oauth2-proxy in general? If the maintainers don’t use it anymore, is there a recommended alternative?
+1 for this. I’ve got auth working fine with static upstream configuration without errors middleware, but problem is that I’m trying to add
allowed_groupsto/oauth2/authendpoint for forwardauth middleware. IIUC this can’t work without redirects/errors middleware, as oauth2-proxy will just return 401 for all requests. Does anyone have any ideas how to embeddallowed_groupsquery param into forwardauth middleware with that static upstreams config?Unfortunately I wasn’t able to get auth working at all with errors middleware and querying
/oauth2/startor/oauth2/sign_inon 401-403. I’m getting empty page with “Found” link and CSRF token mismatch error after I press that.Does anyone got working setup for error middleware? Any help will be appretiated.
Hi @lanmarti,
Below my Middleware / IngressRoute Configuration. Don’t forger i use the ForwardAuth with static upstreams configuration not this one ForwardAuth with 401 errors middleware
The hack from @jonananas (Thanks !) is still required to make this work.
Hi, after further investigation, i found a “missing” part on my Traefik configuration. In fact i try to find oauth2 config to redirect to my website after login but no way always redirect behind oauth2 home page. After apply this paramerter in my traefik config it’s finaly work’s.
Indeed the problem is not on oauth2 config but if the forwarded-headers in traefik is not activated i will not fowarde the X-Fowarded-URI that permit to oauth2 to rediredt to your website after authentification.
I use that config for oauth2-proxy oauth2-proxy.cfg : email_domains = [ “*” ] upstreams = [ “static://202” ] reverse_proxy = “true” redirect_url = “https://mydomain/oauth2/callback” pass_access_token = “true” pass_authorization_header = “true” set_authorization_header = “true” set_xauthrequest = “true” cookie_domains = “.mydomain” whitelist_domains = “.mydomain” skip_provider_button = “true” cookie_secure = “true”
Traefik config (command) : –entryPoints.web.forwardedHeaders.insecure –entryPoints.websecure.forwardedHeaders.insecure
I hope that thing permit to help.
@xoxys Had a similar idea. One issue is that you lose any information about where to redirect after the login succeeds. If you use oauth2-proxy with multiple subdomains this might not be desired. What worked for me: Use a custom template (as described in #1507) and instead of adding a meta redirect, use javascript to set your current url as redirect target (“rd”) and submit the form automatically. This assumes that your url remains unchanged.
This is an ugly hack but I currently don’t see any better way. It seems to me that as long as traefik doesn’t allow changing the status code from 401 to 302 with a custom middleware any redirects coming from oauth2-proxy will have no effect.
Sure, have a look at https://github.com/jonananas/traefik-oauth2-proxy/blob/7f6327ef23ac3be222d2b2516baf271efb9f35b3/oauth_templates/sign_in.html#L69.
Hello, @croneter if it helps, this is how I am using the
sign_in.hmltrick using docker-compose: (PS: a more complete example is here, but it dates from a few month back https://gist.github.com/copolycube/dc6a52812fea19361f5aa5b0f3d514dd )Please reopen this issue, dear @JoelSpeed, it’s still a hassle if not outright impossible to use the traefik errors middleware - which is necessary if you want to control access per subdomain by
allowed_groups+1 that this be reopened as an active issue. This still hasn’t been resolved in the over 3 years since issues with traefik were first reported.
I replaced
/oauth2/sign_inwith/oauth2/startin theoauth-errorsmiddleware. From the user’s point of view, nothing has changed, except that instead of a graphic and a login button, there now is a ‘Found’ url that redirects to our Keycloak when clicked, like the button used to do.The logs are slightly different now, there is no
rdparameter present anymore, but redirecting after login still does not work.I am facing the same issue, a workaround would be to use the headers middleware for each service, which is far away from a good solution.