-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Add support for differing internal vs. public URLs. #1722
base: master
Are you sure you want to change the base?
Conversation
This is helpful with keeping token management traffic purely internal in Kubernetes while still sending back a public-facing link for auth and callbacks.
@coderanger Can you elaborate on the use case for this and how it works? As far as I was aware, the issuer URL should match the endpoint that the user hits at all times as part of the OIDC spec, is this not the case? Is there precedence for this being done elsewhere? |
The spec does say that and it makes sense when the issuer is Google, but when trying to set things up for an internal-only service it's nice for internal-only traffic like |
@coderanger I can see why this is potentially useful, but I'd like to get more context about what the spec says about such implementation, so if you could quote or point us to the relevant section of the spec, that would be great. Thanks! |
As I read through the spec to try and answer that question, I guess actually the spec never specifically states that the authentication endpoint has to be "under" the issuer URL. In fact while the issuer ID needs to be a valid URI, it has no actual connection to the network address of the IdP or any of the endpoints. https://openid.net/specs/openid-connect-discovery-1_0.html#IssuerDiscovery makes this explicit for Issuer Discovery, but the only specific requirement on authorization endpoints is that they use TLS (https://openid.net/specs/openid-connect-core-1_0.html#AuthorizationEndpoint). |
Thanks for those links and doing the research. I think you're right, this doesn't break the spec. It does raise the question to me though, can you not manually configure the clients? Since discovery is an optional implementation, your clients should be able to manually configure the token, key and userinfo endpoints right? Does this maybe break the serve mux that Dex has built in 🤔 I guess this is only useful in scenarios where all clients in your configuration can access the internal endpoints? Eg, you couldn't use something like a command line login for users with this? I think it would be good to update the description of the PR to explain in a bit more detail the motivation and usage of this change, plus we should ideally update the docs to explain the new feature |
We are trying to solve similar problem, where this PR can help. We are developing application (consisting of several services), where we need authentication. We decided, that we will only support OIDC to make implementation more simple. This is not possible to achieve using single issuer URL. It is possible to workaround most of problems using OIDC client configuration, but we can not influence URLs generated by |
Never-mind - we were able to achieve required behavior only with Spring Security configuration - it was incorrectly documented, so some reverse engineering showed possible approach. |
Auth: s.absURL(s.publicURL, "/auth"), | ||
Token: s.absURL(s.issuerURL, "/token"), | ||
Keys: s.absURL(s.issuerURL, "/keys"), | ||
UserInfo: s.absURL(s.issuerURL, "/userinfo"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't this quite arbitrary? The userinfo endpoint can be called by public clients as well.
Seems to me that the entire feature would be better handled on client side, and not in Dex.
E.g. in our backend code, we manually rewrite the host of the endpoint, to directly connect to the Dex container hostname instead of the public endpoint.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure what you mean, /auth is the only thing that needs to be "public" because that's what is used when bouncing users to the underlying backend. The rest are using by authentication consumers, which in many cases are entirely internal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If there is a way to do this client-side without violating the spec, I'm all ears.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
E.g. a single-page app (using PKCE or Implicit Flow) may call the userinfo endpoint from the browser.
I was assuming that "public URL" = called from browser, "internal URL" = called from backend.
If there is a way to do this client-side without violating the spec
Not that I'm aware of... Rewriting the URL was just a pragmatic solution that worked for us.
What could also work, if public and internal URLs use the same scheme (HTTP / HTTPS): Add an /etc/hosts
entry for the backend that should use the internal endpoint, like <public_dex_hostname> <internal_dex_ip>
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure but that SPA would be a client so you wouldn’t enable this mode. This is specifically for the case of all clients are internal but the IdP isn’t (google in my case). This is common in the use case of using Dex for Kubernetes authentication.
This is exactly our situation. Could this be reconsidered? |
This is helpful with keeping token management traffic purely internal in Kubernetes while still sending back a public-facing link for auth and callbacks.