Forward authentication response headers
Do you want to request a feature or report a bug?
Feature
What did you expect to see?
It would be useful to allow headers returned from the forward authentication HTTP endpoint to be added to the final HTTP response. This would allow scenarios where the forward authentication endpoint can refresh authentication credentials and add the new credentials as a header/cookie.
This can be accomplished with a new configuration for http forward auth of "addHeadersToResponse" or similar.
Example:
addHeadersToResponse = ["Set-Cookie"]
This would result in any cookies added from HTTP forward auth response to be returned with the final response to the requesting client.
End-to-End example.
- Traefik receives request to entrypoint with forward auth.
- Traefik forward request to auth HTTP URI
- JWT is used as a cookie for authentication. Forward auth server validates JWT, but expiration of JWT is soon.
- Forward auth server requests new JWT for user and uses "Set-Cookie" header to overwrite previous JWT. Returns 20* response telling Traefik to continue routing.
- Request is routed to correct frontend/backend and response obtained.
- Forward auth middleware adds "Set-Cookie" header to outgoing response with new JWT.
- New JWT cookie is used for subsequent requests.
Duplicate of #3515
Fixed by #3521
@ldez I don't think this is a duplicate. Unless I'm missing something that solution allows headers to be added to the request that is sent to the backend. The use case above requires the headers to be added to the outgoing response.
I could really use this.
We use a Rails server for authentication, and use forward authentication to convert the cookie to a JWT for other services. This works great, but doesn't allow the cookie to get updated.
My Kubernetes Ingress configuration looks like this
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: example
annotations:
kubernetes.io/ingress.class: traefik
ingress.kubernetes.io/auth-type: forward
ingress.kubernetes.io/auth-url: http://example-rails.default/authenticate
ingress.kubernetes.io/auth-response-headers: Authorization
ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: example.com
http:
paths:
- path: /api
backend:
serviceName: example
servicePort: 80
A possible workaround is to add Set-Cookie to ingress.kubernetes.io/auth-response-headers and then have the service copy the header to the response itself; but that requires that the service know about the cookie. In this case, I want the service to only know about JWTs.
http://example-rails.default/authenticate
ingress.kubernetes.io/auth-url: http://example-rails.default/authenticate
Is the auth-url is k8s inner service address? Using inner service address as auth-url don't work! Are you encounter?Thanks
@0x457 using a k8s service url does work, I have a service using this with oauth2-proxy.
How to use oauth2-proxy? Are there any examples?
@0x457 using a k8s service url does work, I have a service using this with oauth2-proxy.
Where's some example about oauth2-proxy? 👍
Hi. I have the same issue here.
I want to use an external bot protection service which return a 200 or 401 according to the user agent / source IP etc.. It Also set a Cookie via the Set-Cookie Header which is not forwarded to the client response but only to the application backend.
Ideally Traefik should merge the cookies set by the application with the cookies set by the auth forward service.
We have the same issue, with our forwardAuth service to manipulate the cookies. Would like to propose as a draft #4730 (cannot tag because issue is closed)
Hi, I'm gonna try to solve this soon, just wanted to clarify something before writing code:
I've just dived to the problem with overwriting headers. So, what I think is we have 3 cases:
- Set-Cookie header is allowed to be set multiple times for different cookie names. rfc6265. So there should not be problem with that.
- Set-Cookie sent from forwardAuth service should be overwritten by target service in case they have same cookie names.
- For all the other headers values must be concatenated
Is this this the right behaviour?
Any progress on this? I am using it on Swarm and have the same issue. For now I am leaving my services without refreshing the cookies.
We're stumbling over the same issue right now, and need to set refreshed access tokens from our forward-auth middleware backend. We're currently running a workaround with sending a 307 redirect to the same URI to set headers which works surprisingly well, but we'd prefer to set the cookie directly, without the forward that will probably break some APIs.
My analysis of the situation so far (enumeration just for easier discussion):
- in general, the HTTP RFCs do not have a requirement on "repeated" headers, unless a proxy may not change their order; adding them seems fine
- there is a requirement on duplicate set-cookie headers on the same cookie key, which should not be sent following RFC 6265
- we could prefer the auth server cookies
- we could prefer backend cookies
- we could leave the choice to the administrator/middleware configuration
- a rather naïve implementation like the one in #6893 will not be able to fulfill RFC 6265, but a proper wrapping response writer would be required to handle this
- traefik already has such a wrapper in the header middleware
pkg/middlewares/headers/responsewriter.go(which does not (yet) conform to RFC 6265 either, though; at least I did not find any code indicating so) - this cannot be easily reused yet, as the configuration happens in unexported fields/functions (ie.
newResponseModifier)
My proposal would be to:
- implement RFC6265 compliant behavior for the header plugin, which following discussion in #6893 is a bug
- reuse the already implemented and tested
responsewriter.goby exporting required fields/methods
- should the code be moved to some kind of util package in this case? I did not find an obvious place yet
- add configuration to the forward auth plugin to define what cookies should be merged
- probably somewhat aligned to how the add header plugin does the configuration
- we need to think about, which headers should come first (backend or auth server), which also implies which system will potentially be able to override cookies from the other
If we can agree on this concept, I'd be ready to jump in with the required code.
CC @ldez @jbdoumenjou since you discussed previous approaches on this issue.
As we have the same requirements than the others here: Any news on the issue ? What about the proposal of @JensErat ?
AFAIS all posts here needs the "set-cookie" header, so only merge cookies (instead of headers) would be sufficient. Using all configured cookies from auth response and the remaining (i.e. without the configured ones) cookies from backend would satisfy:
- No duplicate cookie names according to RFC
- As the cookies from auth server has higher priority, the backend can't overwrite the security relevant cookies from auth server.
Hello ! I'm also in need of such a feature!
I'm using docker with services accessible on *.maison (ex: grafana.maison), cross-domain cookies don't work, I need my middleware to be able to pass a Set-Cookie to the user (so that the middleware can control the cookies).
Edit : the https://plugins.traefik.io/plugins/63b899ec3038a467c0ee9cb5/add-response-header plugin seems to do the trick for a certain amount of overload; in my case, I could also use sub-domains, but being local, that would mess up the URLs
Closed by #8924