Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

LuanP
Copy link

@LuanP LuanP commented Mar 25, 2019

  • Update lua-resty-openidc to 1.7.1-1
  • Add redirect_uri field to schema and sending it to lua-resty-openidc

@jerfer
Copy link

jerfer commented May 17, 2019

@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
Copy link
Author

LuanP commented May 18, 2019

@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
Copy link

jerfer commented May 18, 2019

@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
Copy link
Author

LuanP commented May 18, 2019

@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
Copy link

jerfer commented May 18, 2019

@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
Copy link

jerfer commented May 19, 2019

@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
Copy link
Author

LuanP commented May 22, 2019

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
Copy link

jerfer commented May 22, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants