traefik-forward-auth
traefik-forward-auth copied to clipboard
How to authenticate endpoints with a path?
Take the simple-separate-pod example and modify it to have a path:
---
# Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: whoami
labels:
app: whoami
annotations:
kubernetes.io/ingress.class: traefik
traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip # <--- see explanation below
ingress.kubernetes.io/auth-type: forward
ingress.kubernetes.io/auth-url: http://traefik-forward-auth:4181
ingress.kubernetes.io/auth-response-headers: X-Forwarded-User
spec:
rules:
- host: whoami.example.com
http:
paths:
- path: /foo/ # <-------------------------------------------- add this
backend:
serviceName: whoami
servicePort: http
Then navigate to https://whoami.example.com/foo/ (replace the host with your actual host). The authentication flow is started and then the user is redirected back to https://whoami.example.com/_oauth.
That page then shows
404 page not found
which makes sense because on https://whoami.example.com/ there is no forward auth configured, only on https://whoami.example.com/foo/.
I couldn't find any configuration to make this work. I believe there are two ways to solve it, but both require changes in Traefik Forward Auth.
Possibility 1: Use X-Forwarded-Prefix
If you add the annotation traefik.ingress.kubernetes.io/rule-type: PathPrefixStrip (see above) to the Ingress, Traefik will strip the /foo/ from the path before forwarding the request to Traefik Forward Auth. It will however add a header X-Forwarded-Prefix containing the /foo/ part. Traefik Forward Auth could simply add this to the redirect URL, so that it becomes https://whoami.example.com/foo/_oauth.
This is actually #49.
Possibility 2: Use Auth-Host mode
I tried switching to the Auth-Host mode. This solution is slightly inferior because it requires all authenticated hosts to run under one common cookie domain. (By the way, there is no error when AuthHost is set but CookieDomain isn't, the AuthHost will simply be ignored, making debugging difficult.)
When AuthHost is set, the authentication itself seems to work, but the following redirect back to the application is missing its path. The solution is simple: Don't discard the path when redirecting to the application.
Hi - thanks for the detailed and well written question :)
You're right - they're two good ways to solve the issue, I'm keen to get #49 merged which would offer quite a nice solution to this.
Another option would be to manually add the path, using the traefik 1.7 as per your example:
---
# Ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: whoami
labels:
app: whoami
annotations:
kubernetes.io/ingress.class: traefik
ingress.kubernetes.io/auth-type: forward
ingress.kubernetes.io/auth-url: http://traefik-forward-auth:4181
ingress.kubernetes.io/auth-response-headers: X-Forwarded-User
spec:
rules:
- host: whoami.example.com
http:
paths:
- path: /foo/
backend:
serviceName: whoami
servicePort: http
- path: /_oauth
backend:
serviceName: whoami
servicePort: http
?
Interesting idea. I actually have no idea what would happen, but I guess Traefik would just send the request to any of the Ingresses that have this path set? And it doesn't matter which one, because they all ~~end up at the same service~~ trigger the same auth-url? I'll try that out right away.
Edit: Doesn't work, I'm getting a redirect loop:

I'll have a test with this to see if it's possible
Also, notice that enabling traefik-forward-auth globally (in Kubernetes and traefik2 this is done with the argument "--entrypoints.web.http.middlewares=default-traefik-forward-auth@kubernetescrd"), make the last redirect works. Still don't know why, but experimentally, at least for me, it is like that.