thomseddon / traefik-forward-auth

Minimal forward authentication service that provides Google/OpenID oauth based login and authentication for the traefik reverse proxy
MIT License
2.08k stars 396 forks source link

Auth style probing results in AWS Cognito invalid grant #259

Open ghost opened 3 years ago

ghost commented 3 years ago

Traefik Forward Auth appears to be utilising the default behaviour of the underlying Golang oauth2 library (https://github.com/golang/oauth2/blob/master/internal/token.go#L188) and attempts to detect the auth style by sending multiple probes. The probing appears to be incompatible with AWS Cognito and results in an invalid grant (HTTP response 400) on the second auth style probe.

Would it be possible to add support for a new environment variable (https://github.com/thomseddon/traefik-forward-auth/blob/master/internal/provider/generic_oauth.go#L42 - auth style parameter) to set the Golang oauth2 auth style (https://github.com/golang/oauth2/blob/f6687ab2804cbebdfdeef385bee94918b1ce83de/clientcredentials/clientcredentials.go#L106)?

thomseddon commented 3 years ago

Yes indeed, good idea, we already have "TokenStyle" to "AuthStyle" could work similarly

Obirah commented 2 years ago

Hey guys, I started working on this issue as I urgently need to use traefik-forward-auth with Cognito OIDC.

This is my first shot: https://github.com/Obirah/traefik-forward-auth/commit/7daa87b0ea484d7a7850df8c637ffb1c1dc3d20c

However, I'm still a golang newbie and now I'm facing the problem that I'm getting an invalid_client error instead of the invalid_grant error whenever I'm setting one of the two explicit auth styles instead of "auto-detect" (0). It looks like client ID and secret are not sent at all when using those styles.

Do you have any idea what I'm doing wrong? If I get this thing to work, I'll of course happily contribute the change.

Obirah commented 2 years ago

Ok, I solved my problem. My changes are working, the error was caused by my redirect URL (I'm using AUTH_HOST) starting with http:// (I think because the traefik-forward-auth service uses http) which Cognito never accepts.

So, I simply had to add this Middleware to my auth host IngressRoute:

---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: add-https-headers
spec:
  headers:
    customRequestHeaders:
      X-Forwarded-Port: '443'
      X-Forwarded-Proto: https

I will provide a Pull Request for this issue shortly.

MatteoGioioso commented 2 years ago

@Obirah I have your same issue, the callback is http, but I need https, not sure this is a bug happening only with Cognito. Where did you add that middleware? I have added it in my host as well, but it does not seems to work.

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: traefik-dashboard-ingress
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`myhost.com`)
      kind: Rule
      services:
        - name: api@internal
          kind: TraefikService
      middlewares:
        - name: traefik-forward-auth
        - name: add-https-headers

I am trying to expose the traefik dashboard

MatteoGioioso commented 2 years ago

For the time being I have modified the code and upload my own image:

func redirectBase(r *http.Request) string {
    return fmt.Sprintf("%s://%s", "https", r.Host)
}

Unfortunately I could not find any solution other than hard-code the https protocol

Obirah commented 2 years ago

I'm using the following middlewares:

Authentication:

---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: forward-authentication
spec:
  forwardAuth:
    address: http:/my-forward-auth-service.my-forward-auth-namespace.svc:4181
    authResponseHeaders:
      - "X-Forwarded-User"
    trustForwardHeader: true

HTTPS:

---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: add-https-headers
spec:
  headers:
    customRequestHeaders:
      X-Forwarded-Port: '443'
      X-Forwarded-Proto: https

Composition of both:

---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
  name: authenticate
spec:
  chain:
    middlewares:
      # Necessary to consistently stick with HTTPS URIs in the redirect ping-pong with Cognito.
      - name: my-forward-auth-namespace-add-https-headers@kubernetescrd
      - name: my-forward-auth-namespace-forward-authentication@kubernetescrd

I can add the last one (the authenticate Middleware) on any Ingress/IngressRoute and it will authenticate against Cognito. Please note, when working with Cognito this will only work when using my changes from this Pull Request and the <PROVIDER_NAME>_AUTH_STYLE set to header until @thomseddon merges my change. So ideally, you should pull my fork and create your own image, if you need that.

MatteoGioioso commented 2 years ago

Please note, when working with Cognito this will only work when using my changes from this Pull Request and the _AUTH_STYLE set to header

Aha, gotcha. Thanks man!