OIDC with Gitlab

Even with https://github.com/coder/coder/pull/5507 merged have no success with gitlab as OIDC provider. If I put a debug print of the claims data here: https://github.com/coder/coder/blob/main/coderd/userauth.go#L253 I something like this:
{"request_id": "b4bdb687-ebc3-4417-859a-30a801a14900", "Username": {"aud": "d5d9aadca67c0f49b2b7184c1904f2b602ed658f7902183f42fc36b94f945847", "auth_time": 1673612004, "email": "[email protected]", "email_verified": true, "exp": 1673882335, "groups_direct": ["aaa", "bbb", "ccc"], "iat": 1673882215, "iss": "https://gitlab.xxx.de", "sub": "7", "sub_legacy": "46e97dbbd9e7fd062ff2b6413072f0f634652eef58735409ea59638889c4e804"}}
{"request_id": "b4bdb687-ebc3-4417-859a-30a801a14900", "Username": {"aud": "d5d9aadca67c0f49b2b7184c1904f2b602ed658f7902183f42fc36b94f945847", "auth_time": 1673612004, "email": "[email protected]", "email_verified": true, "exp": 1673882335, "groups_direct": ["aaa", "bbb", "ccc"], "iat": 1673882215, "iss": "https://gitlab.xxx.de", "sub": "7", "sub_legacy": "46e97dbbd9e7fd062ff2b6413072f0f634652eef58735409ea59638889c4e804"}}
The nickname is completely missing. Has anyone an idea what I do wrong?
GitHub
feat: allow configurable username claim field in OIDC by janLo · Pu...
Gitlab does not set the preferred_username field. Therefore, coder generates something from the user's email address, which is not very helpful. This allows the administrator to change the fiel...
GitHub
coder/userauth.go at main · coder/coder
A tool that provisions remote development environments via Terraform - coder/userauth.go at main · coder/coder
32 Replies
JanL
JanLOP2y ago
By default all custom claims are only returned from the UserInfo endpoint and not included in the ID token. You can optionally pass a response: keyword with one or both of the symbols :id_token or :user_info to specify where the claim should be returned.
JanL
JanLOP2y ago
GitHub
GitHub - doorkeeper-gem/doorkeeper-openid_connect: OpenID Connect e...
OpenID Connect extension for Doorkeeper. Contribute to doorkeeper-gem/doorkeeper-openid_connect development by creating an account on GitHub.
JanL
JanLOP2y ago
could this be teh reason? Can I somehow "fix" this? (on the coder side)
kyle
kyle2y ago
Hmm, interesting. I'm not exactly sure how we'd go about fixing it. To be certain I'm following, you need the "nickname" claim to appear for a username, but it seems to only pass that if special parameters are passed to the request?
JanL
JanLOP2y ago
No, you need to request this from the user info endpoint after fetching the id token. https://pkg.go.dev/github.com/coreos/go-oidc/v3/oidc#Provider.UserInfo I can try to implement it myself but might need some help with the unittests (client mocking) as I'm not a regular go developer. I'll in parallel open an issue at gitlab to provide basic information within the id token maybe. Not sure it was a deliberate decision on their side to only make this available within the user info ep
kyle
kyle2y ago
I see! Is id_token returned?
JanL
JanLOP2y ago
Yes The id token is apparently the only MUST part in the standard
kyle
kyle2y ago
Ahh, gotcha. So if there are no claims, then we should be executing the Provider.UserInfo call?
JanL
JanLOP2y ago
exactly
JanL
JanLOP2y ago
This does the trick.
JanL
JanLOP2y ago
The only thing is - now the unittests need to be fixed and I have no capacity in at the moment to understand the http client mocking
kyle
kyle2y ago
Neato. I'll put up a fix right away and we can do a release for you!
JanL
JanLOP2y ago
Shall I create a PR anyway?
kyle
kyle2y ago
Thanks for investigating 🙂 Nah, I'll just steal your patch. I'll mention your GH username @JanLo
JanL
JanLOP2y ago
thank you!
kyle
kyle2y ago
I'm going to do this in a bit of a different way. My code is going to assume that the id_token has zero claims attached - is that a fair assumption?
JanL
JanLOP2y ago
I cannot really tell if that is always true, the OIDC standard says, it can be in either or. For gitlab this is true - but this is only one provider
kyle
kyle2y ago
But in this specific case is it true?
JanL
JanLOP2y ago
This specification defines a set of standard Claims. They can be requested to be returned either in the UserInfo Response, per Section 5.3.2, or in the ID Token, per Section 2.
ah, you mean, fetch user info if no claims are attached?
kyle
kyle2y ago
Yup! Current code:
if len(claims) == 0 {
userInfo, err := api.OIDCConfig.Provider.UserInfo(ctx, oauth2.StaticTokenSource(state.Token))
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to obtain user information claims.",
Detail: "The OIDC provider returned no claims as part of the `id_token`. The attempt to fetch claims via the UserInfo endpoint failed: " + err.Error(),
})
return
}
err = userInfo.Claims(&claims)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to unmarshal user info claims.",
Detail: err.Error(),
})
return
}
}
if len(claims) == 0 {
userInfo, err := api.OIDCConfig.Provider.UserInfo(ctx, oauth2.StaticTokenSource(state.Token))
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to obtain user information claims.",
Detail: "The OIDC provider returned no claims as part of the `id_token`. The attempt to fetch claims via the UserInfo endpoint failed: " + err.Error(),
})
return
}
err = userInfo.Claims(&claims)
if err != nil {
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
Message: "Failed to unmarshal user info claims.",
Detail: err.Error(),
})
return
}
}
Not sure if it returns no claims though. If it returns some claims, then we have a wonky situation ;p
JanL
JanLOP2y ago
that is not true, gitlab strange enough sends teh direct group memberships and the user email in the id_token claim
kyle
kyle2y ago
Hmm, very unfortunate
JanL
JanLOP2y ago
yes. I'm not sure if they created this situation deliberately or if it happened just because someone did not fully read the documentation of the library they used 😉 I'll definitely open an issue on the GL side For this case, I think it's acceptable to do this extra work on the coder side becuase this code is only hit if someone provided a valid oidc callback anyway - so I don't see much potential for dos
kyle
kyle2y ago
@JanL PR almost up!
JanL
JanLOP2y ago
Oh wow, thank you so much!
kyle
kyle2y ago
@JanL can you build from main to try it out? Or do you need us to cut a release?
JanL
JanLOP2y ago
I'll test it first thing tomorrow morning, I've turned my device off already. Is it alright to cherry-pick just this commit on top of the last release? Then I don't need a separate release for just this change.
kyle
kyle2y ago
Yup, you should be able to cherry it! Let me know if there are any issues!
JanL
JanLOP2y ago
👍 Sorry for the late feedback, I got distracted this morning. The patch works perfect. Thank you!
kyle
kyle2y ago
Awesome!
Want results from more Discord servers?
Add your server