external-auth-server icon indicating copy to clipboard operation
external-auth-server copied to clipboard

Using variable in redirect_uri

Open gfrankliu opened this issue 2 years ago • 6 comments

I am testing external-auth-server behind nginx ingress with path prefix /auth. Ingress will strip out /auth before passing to external-auth-server.

When defining redirect_uri for oidc plugin, is it possible to use variable, eg: $host, for the base URL? The Host header comes in from the Ingress. Also, how to tell external-auth-server that it is running behind the ingress reverse proxy, so the redirect URI will need to be /auth/oauth/callback, instead of /oauth/callback?

gfrankliu avatar Jul 25 '23 07:07 gfrankliu

Welcome! I don’t recommend doing that. I would dedicate a hostname for eas and be sure that eas isn’t authing itself.

Are you setting the redirect uri in the token or letting eas auto-generate that? Can you send over a sample/scrubbed token to review?

It may be possible to add a prefix configuration option but I’d have to audit exactly where it’s getting used and how.

travisghansen avatar Jul 25 '23 13:07 travisghansen

Thanks @travisghansen for this great product and fast responses! I checked a few other auth repos on github, most are stale with no responses to posts in the issues at all.

Here is my config token:

# use jwt token from auth provider 1 if exists, otherwise trigger oauth from provider 2
eas:
  plugins:
    - type: jwt
      header_name: my-jwt-header
      config:
        secret: https://www.provider1.com/public_key-jwk.json
        options:
          audience: /special/audience/for/me
          issuer: https://www.provider1.com
      pcb:
        skip:
          - query_engine: jp
            query: $.req.headers.my-jwt-header
            rule:
              method: regex
              value: /^bearer/i
              negate: true
    - type: oidc
      issuer:
        discover_url: https://www.provider2.com/.well-known/openid-configuration
      client:
        client_id: aaaaa
        client_secret: bbbb
      scopes:
        - openid
        - email
        - profile
      pkce:
        enabled: true
        code_challenge_method: S256

I am hoping to add redirect_uri: "/oauth/callback" to provider 2 section and let external-auth-server to build the redirect_uri using current $host header, something like https://$host/oauth/callback

gfrankliu avatar Jul 25 '23 16:07 gfrankliu

Wow! You have quickly grasped the vision! You can set a fqdn/uri as the redirect uri but you’ll have to be aware of and explicitly manage the cookie domains etc. I would suggest to read this if you haven’t already: https://github.com/travisghansen/external-auth-server/blob/master/OAUTH_PLUGINS.md

If you cannot run the service without a prefix we can likely get something added but I would need to check several locations to be complete as I support single sign out and other features which expect specific endpoints as well. It would take a minute to audit it all.

travisghansen avatar Jul 25 '23 16:07 travisghansen

Regarding the prefix, I have nginx ingress in front with below config:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: eas
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /auth(/|$)(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: eas
            port:
              number: 80

The same ingress-nginx has another protected content:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-test
  annotations:
    nginx.ingress.kubernetes.io/auth-url: "https://$host/auth/verify?redirect_http_code=401&config_token_store_id=store1&config_token_id=token1"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/auth/nginx/auth-signin?rd=$auth_redirect"
    nginx.ingress.kubernetes.io/auth-response-headers: X-Userinfo,X-Id-Token,X-Access-Token
    nginx.ingress.kubernetes.io/rewrite-target: /$2
    nginx.ingress.kubernetes.io/configuration-snippet: |
      auth_request_set $auth_redirect $upstream_http_location;
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /protected/(.*)
        pathType: ImplementationSpecific
        backend:
          service:
            name: test-backend
            port:
              number: 80

Instead of "configuration-snippet", can external-auth-server expose an signin endpoint so we don't do multiple redirects? When testing oauth2-proxy, all I need is to use:

    nginx.ingress.kubernetes.io/auth-url: "https://$host/oauth2/auth"
    nginx.ingress.kubernetes.io/auth-signin: "https://$host/oauth2/start?rd=$escaped_request_uri"

Maybe we could do the same here?

gfrankliu avatar Jul 25 '23 16:07 gfrankliu

Maybe we could introduce a new env like EAS_RP_PREFIX that defaults to / , but can be changed for using Reverse Proxy with a different prefix such as /auth in my case.

For now, I can add another routing rule in ingress-nginx to route /oauth/callback to external-auth-server without stripping the /oauth, but the question remains for the dns name. I tried setting redirect_uri: "/oauth/callback" but don't see base dns name being added when the request is sent to the provider. I am trying to use the same config token for multiple test environments with different ingress dns names (eg: dev, qa, int). Is it possible not to include the dns name in redirect_uri?

gfrankliu avatar Jul 25 '23 18:07 gfrankliu

Ah I see, currently no, the expectation if that value is set is that it's a full uri, not just a path. You could create distinct tokens for each domain and use server-side tokens + config_token_id_query_engine AND config_token_id_query to dynamically select the token based on domain name.

https://github.com/travisghansen/external-auth-server/blob/master/CONFIG_TOKENS.md#server-side-tokens

To be clear, I'm not against expanding the feature, it's just not implemented to meet your need currently.

travisghansen avatar Jul 26 '23 00:07 travisghansen