I am currently trying to get dex working in a ruby environment. On the RP side I am currently working with omniauth-openid-connect, which has some issues of its own.
However: Working around some of those initial issues, I am now stuck with omniauth-openid-connect trying to get additional claims from the userinfo endpoint, which is not implemented by dex.
In reading the OIDC specification, I failed to recognize whether this is a mandatory endpoint or an optional endpoint, but since it appears right away in section 1.3 of the spec, I would _assume_ it is mandatory.
Are there any plans on implementing this endpoint?
If not, I _might_ start working on it, but that depends on a number of other factors and it would be my first larger golang contribution anywhere, not to mention that I have barely read enough of the specs...
It's recommended, not mandatory:
userinfo_endpoint
RECOMMENDED. URL of the OP's UserInfo Endpoint [OpenID.Core]. This URL MUST use the https scheme and MAY contain port, path, and query parameter components.
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
We currently add additional claims to the ID Token. For example:
{
"aud": "example-app",
"email": "[email protected]",
"exp": 1458191394,
"iat": 1458148194,
"iss": "http://127.0.0.1:5556",
"name": "Elroy Jonez",
"sub": "elroy-id"
}
But yes, we should absolutely have a userinfo endpoint.
I was just thinking today how the UserInfo endpoint would be useful for some integrations on account.tectonic.com. Particularly for syncing user accounts to other services.
This would actually be really easy, since we currently use the ID Token as the access token[0]. We'd just decode that for the user.
[0] https://github.com/coreos/dex/blob/2d5fb0b47a3150d4fb2696f0736c12ee57d72ba7/server/http.go#L495-L500
Is this still planned? I would like to see this implemented before 2.0 gets final.
Is this still planned?
This isn't since all information we'd return with a userinfo endpoint is already returned in the id_token.
Also, right now nothing uses the access_token returned by dex v2 (it's actually just a random string), so implementing this requires some design around what an access_token is internally to dex.
I understand that their are clients that require this optional endpoint, but it's not a high priority for us.
Proposal:
Let's backpack off the proto types add for refresh tokens in https://github.com/coreos/dex/pull/757 to implement an access token. The token will look like:
message AccessToken {
string subject = 1;
string name = 2;
string email = 3;
bool email_verified = 4;
// Time at which the access token expires, represented as a unix time.
//
// This is the same value as the id_token.
int64 expiry_unix = 5;
}
The access token fields will be filled out by the Claims in the AuthCode struct[0].
The access token struct will be serialized, then signed as a JWS using the signing keys maintained by dex, and returned as the "access_token" payload. When a user hits the userinfo_endpoint the key ID of the JWS is used to lookup the internal key, which is verified then used to form the userinfo_endpoint response.
On a refresh, the new access_token is returned.
We also may consider using ECDSA keys if the signature is significantly shorter.
Because access_tokens are opaque to the end user, we can internalize this logic later if we need to if the access_token gets too big.
[0] https://godoc.org/github.com/coreos/dex/storage#AuthCode
Seems like a great approach. This is almost exactly what the OIDC spec recommends if your attempting to build a stateless OIDC provider too.
We also might consider encrypting the token instead of signing it. Just to make sure no one tries to rely on our access_token format.
A userinfo endpoint is required to pass the basic OpenID Connect Conformance Profile to achieve certification.
Certification issue: #42
I am trying to use dex with spinnaker and it needs the userInfoUri endpoint. Without this it's not possible to use dex with it.
See https://www.spinnaker.io/setup/security/authentication/oauth/#bring-your-own-provider
Same w/ anyone attempting to integrate with Centrify. Centrify doesn't include any of the expected data in that id_token JWT. The expectation is that you will call the userinfo endpoint to gain the detail you are looking for.
details here: https://docs.centrify.com/en/centrify/appref/index.html?version=1507675723#page/cloudhelp%2Fgen%2FSAML-gen-OpenID.2.html
The same issue happens when integrating with the GenericOAuthenticator module used by JupyterHub for OpenID Connect authentication.
It also expects the Userinfo endpoint on the provider to exist to fetch user details.
I am trying to use dex as an authentication provider with GitLab, and the omniauth-openid-connect gem which GitLab uses requires the userinfo endpoint as well.
I understand the philosophical standpoint that all information should be taken from the token, but at the same time, it seems like this stanza prevents using dex with a wide variety of software, which is a real shame.
Please consider the pragmatic solution of implementing the userinfo endpoint. Thank you!
Will work on this in the upcoming weeks and submit a proposal for review
That鈥檚 great news! Thank you.
@rithujohn191 I forked Dex and successfully implemented the User Info endpoint. I will share it as soon as I finish polishing it, but I will give some details on how it works.
Connectors of type oidc have a new configuration option userInfo where a user info endpoint for the OP can be provided. E.g.:
- type: oidc
id: google
name: Google
config:
issuer: https://accounts.google.com
userInfo: https://www.googleapis.com/oauth2/v3/userinfo <<<<<<
clientID: $GOOGLE_CLIENT_ID
clientSecret: $GOOGLE_CLIENT_SECRET
redirectURI: http://127.0.0.1:5556/dex/callback
hostedDomains:
- $GOOGLE_HOSTED_DOMAIN
How it works technically:
Note: I did not consider token refresh.
This has only be tested with the generic OAuthenticator plugin of Jupyterhub which uses a basic OAuth2 flow.
@fjbsantiago Does your implementation also work with other connectors like LDAP?
@markuslindenberg Sorry, but I only implemented this for Open ID Connect connectors, unfortunately.
Just a heads up. Any dex user info implementation we add to dex will work with any backing connector (LDAP, SAML, GitHub, etc), not just with OpenID Connect.
I have another quick question @ericchiang.
Some OPs return different kinds of claims from the userinfo endpoint like, for example, birth date and gender.
Will these claims be lost if you implement the Access Token as per your proposal?
@NobodysNightmare I wrote an implementation for the UserInfo endpoint. It is currently pending as a pull request.
It would be nice if you could try it to see if it solves your issue with omniauth-openid-connect, unless you already found a workaround.
@fjbsantiago I have made a simple test of your code as openshift(kubernetes) auth provider
As i reviewed openshift openid plugin code
https://github.com/openshift/origin/blob/9a9a948e55f943e1aa2cff3965a7545f7809a380/pkg/auth/oauth/external/openid/openid.go#L187
and
http://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
I think the subject in AccessToken should be the same as in id_token
https://github.com/coreos/dex/pull/1133/files#diff-105fedf355a9fcad82982745cef24f7aR1055
@hardbone12 rolled my own, borrowed mostly from @fjbsantiago , fixed the subject issue
Hey Folks, any news on this?
Since I am not familiar with all flows and OIDC specifications, I have some dummy questions:
I've created a PR which adds userinfo_endpoint based on the current code and the previous PR from @jackielii https://github.com/dexidp/dex/pull/1454. Also available as a Docker image from https://hub.docker.com/r/mdbraber/dex
Most helpful comment
Will work on this in the upcoming weeks and submit a proposal for review