nokia / kong-oidc

OIDC plugin for Kong
Apache License 2.0
454 stars 320 forks source link

Update lua-resty-openidc to 1.7.1-1 and add redirect_uri #114

Open LuanP opened 5 years ago

LuanP commented 5 years ago
jerfer commented 5 years ago

@LuanP Can you provide an example of how this would be configured?

Specifically, I'm trying to get this to work with a single redirect endpoint (e.g. https://auth.example.com/callback) for all of my upstreams (e.g. https://app1.example.com, https://app2.example.com). So far I've been unable to get it to work apart from all redirects going to the redirect endpoint, nothing makes the next jump to the upstream.

My assumption is that the redirect endpoint cannot just be a "vanity URL" but needs some smarts such that it can parse the redirect and extract the ultimate endpoint from a request param. Can you confirm?

LuanP commented 5 years ago

@jerfer In our application we just created a /callback in one of the routes with the kong-oidc enabled. Also make sure it's the same redirect_uri provided by the OP. But I didn't have to implement anything on that route.

jerfer commented 5 years ago

@LuanP In order for the request_uri parameter to be recognized by lua-resty-openidc, I had to make a change to the code in your PR in the utils.lua/M.get_options() function:

function M.get_options(config, ngx)
  local options = {
    client_id = config.client_id,
    client_secret = config.client_secret,
    discovery = config.discovery,
    introspection_endpoint = config.introspection_endpoint,
    timeout = config.timeout,
    introspection_endpoint_auth_method = config.introspection_endpoint_auth_method,
    bearer_only = config.bearer_only,
    realm = config.realm,
--- >>>--- Change start
    redirect_uri = config.redirect_uri,
--- <<<--- Change end
    scope = config.scope,
    response_type = config.response_type,
    ssl_verify = config.ssl_verify,
    token_endpoint_auth_method = config.token_endpoint_auth_method,
    recovery_page_path = config.recovery_page_path,
    filters = parseFilters(config.filters),
    logout_path = config.logout_path,
    redirect_after_logout_uri = config.redirect_after_logout_uri,
  }

  if not config.redirect_uri then
    options["redirect_uri_path"] = config.redirect_uri_path or M.get_redirect_uri_path(ngx)
  end

  return options
end

But even with this change the redirection still doesn't work properly. Here's what's happening:

  1. I point my browser to http://some_service.example.com/some/path;
  2. Kong is correctly redirecting to the OIDC IdP;
  3. I am successfully authenticated and then redirected to my single redirect_uri, http://auth.example.com/cb

The problem is that I am not then again redirected to http://some_service.example.com/some/path, which I assumed would be the case.

Is my assumption wrong that this is a supported configuration?

What I'm trying to do is avoid having to list all my endpoint paths in my IdP configuration since it doesn't support wildcards on the path portion of redirect URLs, only on the domain-name portion (Auth0). This limitation effectively breaks deep-links unless I can work around it with Kong being able to manage the final redirect from http://auth.example.com/cb to http://some_service.example.com/some/path with the correct cookies set for the authentication.

LuanP commented 5 years ago

@jerfer You shouldn't have to list all your endpoint paths in the provider. Just having a match between the OP-RP is enough.

Regarding the steps you've mentioned, your assumption is correct.

When you try accessing a protected route on your application (through kong and having kong-oidc enabled on that route/service) you'd be redirected to the configured OP, get the authentication, and redirected to the request you were performing before, not the one in the redirect_uri/redirect_uri_path.

It just looks like to be a misconfiguration somewhere. Aren't you seeing any errors in the logs?

jerfer commented 5 years ago

@LuanP Thanks for the confirmation and for taking the time to respond. I really appreciate the help.

No, I'm not getting any errors anywhere so I'll tear everything down and start fresh to make sure I haven't missed anything or made a mistake somewhere.

Did you see my comment about your PR and the M.get_options() function?

Can you provide your (sanitized) OIDC plugin config as well as the ingress config for one of your routes? Being able to compare my configs to yours would help to identify what I'm doing wrong.

Here's my OIDC plugin configuration, note the redirect_uri:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: oidc
  namespace: kong
  annotations:
    kubernetes.io/ingress.class: kong
config:
  client_id: "<client_id>"
  client_secret: "<client_secrect>"
  discovery: "https://my.auth0.com/.well-known/openid-configuration"
  scope: "openid email profile"
  realm: "example.com"
  redirect_uri: "http://auth.example.com/cb"
plugin: oidc

Here's the config I'm using for testing:

apiVersion: apps/v1beta2
kind: Deployment
metadata:
  name: echoservice
  namespace: kong
spec:
  replicas: 1
  selector:
    matchLabels:
      app: echoservice
  template:
    metadata:
      labels:
        app: echoservice
    spec:
      containers:
        - name: echoservice
          image: gcr.io/google_containers/echoserver:1.8
          ports:
            - containerPort: 8080
          env:
            - name: NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP

---

apiVersion: v1
kind: Service
metadata:
  name: echoservice
  namespace: kong
  labels:
    app: echoservice
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
      name: http
  selector:
    app: echoservice

---

apiVersion: configuration.konghq.com/v1
kind: KongIngress
metadata:
  name: echoservice
  namespace: kong
proxy:
  path: /
route:
  protocols:
    - http
  strip_path: false

---

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: echoservice
  namespace:  kong
  annotations:
    kubernetes.io/ingress.class: "kong"
    configuration.konghq.com: echoservice
    plugins.konghq.com: oidc
spec:
  rules:
    - host: echo.example.com
      http:
        paths:
          - path: "/"
            backend:
              serviceName: echoservice
              servicePort: http
---
jerfer commented 5 years ago

@LuanP I figured out the problem. Instead of using the redirect_uri parameter, I can rely instead on a wildcard subdomain as my Auth0 redirect with a hardcoded redirect_uri_path (e.g. http://*.example.com/auth/openid/callback). Kong is then able to successfully redirect from any subdomain/callback to the original request (e.g. http://app1.example.com/auth/openid/callback -> http://app1.example.com/some/path). The clue to all of this was is in #35.

For completeness, here's my working config:

apiVersion: configuration.konghq.com/v1
kind: KongPlugin
metadata:
  name: oidc
  namespace: kong
  annotations:
    kubernetes.io/ingress.class: kong
config:
  client_id: "<client_id>"
  client_secret: "<client_secret>"
  discovery: "https://example.auth0.com/.well-known/openid-configuration"
  scope: "openid email profile"
  realm: "example.com"
  redirect_uri_path: "/auth/openid/callback"
plugin: oidc

On the Auth0 side I configured the Allowed Callback URLs to contain: http://*.example.com/auth/openid/callback, meaning I don't have to add all services and their endpoints to Auth0. The final flow looks like this (simplified):

  1. Unauthenticated request to http://app1.example.com/some/path
  2. Kong redirects to Auth0
  3. User is authenticated
  4. Auth0 redirects to http://app1.example.com/auth/openid/callback
  5. Kong intercepts and redirects to http://app1.example.com/some/path

Thanks again for your help.

LuanP commented 5 years ago

Oh, good work on that man, sorry not being more helpful.

About the comment on the changes, thanks for that, I'll update it here ASAP.

jerfer commented 5 years ago

No worries! You helped more than you think.

Jerry

On Tue, May 21, 2019 at 8:52 PM Luan Pablo notifications@github.com wrote:

Oh, good work on that man, sorry not being more helpful.

About the comment on the changes, thanks for that, I'll update it here ASAP.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nokia/kong-oidc/pull/114?email_source=notifications&email_token=AALMWR3OEEVZO5DJHQ7HZDTPWSKOPA5CNFSM4HA2WN5KYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODV5SVGY#issuecomment-494611099, or mute the thread https://github.com/notifications/unsubscribe-auth/AALMWR6NI2MECWTFN7YRLJ3PWSKOPANCNFSM4HA2WN5A .