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

Configurable OIDC Endpoints Option #486

Open
ChrisJBurns opened this issue Aug 2, 2023 · 2 comments
Open

Configurable OIDC Endpoints Option #486

ChrisJBurns opened this issue Aug 2, 2023 · 2 comments

Comments

@ChrisJBurns
Copy link

Environment
  • lua-resty-openidc=1.7.5
  • OIDC Connect Provider = Keycloak
New Feature Detail

Currently, the way the module get's it's OIDC URLs, is from the discovery URL. Which in most cases is fine, but when running inside of a Kubernetes cluster we'd ideally like to use internal SVC Urls instead of the ingress URL's to avoid the extra hops in network traffic that goes outside of the cluster to come back in.

Because the discovery URL is used for the retrieval of the token, auth, logout URL's (and maybe more), in Keycloak, depending on the host that you use to access the discovery URL, depends on the host you get back in your OIDC urls. For example, if I point the module to Keycloak using the internal Kubernetes service URL like keycloak.namespace.svc.cluster.local/realms/our-tealm/.well-known/openid-configuration, then it will give me back a bunch of URL's like:

...
"issuer": "http://keycloak.namespace.svc.cluster.local/realms/our-tealm",
"authorization_endpoint": "http://keycloak.namespace.svc.cluster.local/realms/our-tealm/protocol/openid-connect/auth",
...

Now as you can imagine, this wouldn't work when the module redirects users to the auth endpoint in a client browser because they cannot access the auth endpoint returned by Keycloak because it's host is an internal Kubernetes service URL. So because of this, users of the module are forced to use the ingress URL's which include extra network hops instead of being able to keep all traffic between the module and the OIDC provider internal to the cluster. This is why I ask if we can add more configurable endpoints so that we can tell the module which URLs to use in certain cases. For example, we could tell it to use the internal Kubernetes SVC URL for the token endpoint as the module is the only one that uses the Token endpoint, it does not give this endpoint to the user. We could also configure it with the public ingress URL for the authorisation endpoint since that endpoint is only going to be used by the user themselves. This would only work if there were no URL's that both the Client browser and the module access, which as far as I'm aware, is the case currently. This allows us to keep traffic inside of the cluster and also use our Service Mesh to encrypt traffic between the module and the Keycloak pod.

What else have we tried?

We have also tried to use http in the discovery URL but things failed because there is a check to verify that the issuer in the id_token is the same as the issuer returned in the discovery URL, and as far as I'm aware there is no way to change the issuer in the id_token that is returned from Keycloak.

@bodewig
Copy link
Collaborator

bodewig commented Aug 4, 2023

Actually, there is a way to set everything that's returned by the discovery endpoint manually. I'm just not sure we've ever documented it. You can set opts.discovery to a table rather than a string and the table needs to contain the same keys as the OpenID Connect discovery spec lists - or rather the subset that lua-resty-openidc actually uses.

So

opts.discovery = {
    issuer = '...' ,
    token_endpoint = '...' ,
}

should work.

@ChrisJBurns
Copy link
Author

Ahhh! I will give it a try!

Although I must add, things are a bit more complicated now as I've just realised, in PKCE flow (which we're using), the request to the token endpoint from the module seems to be a https one - even if the discovery endpoint returns a http URL for the token endpoint. I was having trouble figuring out why that was the case and it turns out I think it's actually an OIDC requirement. So the module must convert it to a https request in that scenario. This makes it slightly more tricky for us as Istio our Service Mesh is responsible for converting http requests into https ones via it's proxy, and in our case we have the module making the https connection directly itself. So we'll have to figure out how to re-route the https request to the internal SVC URL which gets tricky as we don't do anything with certificates as it's all handled by Istio.

Either way, I will try the discovery table that you've described just so we can at least use it and worry about the mandated tls request later on when we've somewhat figured out how to handle it in Istio.

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

No branches or pull requests

2 participants