-
-
Notifications
You must be signed in to change notification settings - Fork 678
Login method m.login.sso
supporting GitHub and OpenID Connect
#2492
Conversation
Code that uses http.NewRequestWithContext will see the same deadline.
This is forked from @anandv96's matrix-org#1374. Closes matrix-org#1297.
This is mostly copied from the ThirdPID, but with a primary key that matches OpenID Connect nomenclature. There's a namspace to ensure other SSO solutions can be supported, but there's only one namespace defined for now.
GitHub implements OAuth2, but not OpenID Connect. This means it needs more magic constants than those that can do OIDC discovery (and where Userinfo is in OIDC-compatible.) Fixes the HTTP client to have a timeout.
* Verbose logging. * Cookie needs a path. * Configurable callback URL. * Various sanity checks.
Requires a configuration change in SyTest.
It ended up without scheme and host. Do what SSORedirect does instead.
So we are one step further now (or a couple) thanks to your last commit. The error I'm receiving now is
https://github.com/tommie/dendrite/blob/loginsso/clientapi/auth/sso/oauth2.go#L168 I took a look at the code but couldn't figure out if something needs to be fixed. We should however have the right tokeninfo endpoint, right? https://openidconnect.googleapis.com/v1/userinfo |
Hmm. I could see two issues:
Fixed those. Status: I'm working on getting the Complement code in shape for a PR. Once this draft works for Google, I'll add some unit tests before it's ready for review. I won't have much time this weekend, though. |
👍
Take your time, we're not in a hurry ;) Okay I got pretty good news :) The localpart is the sub which makes sense as it's truly unique. You mentioned there's no way to select it. I took a look at how matrix.org does it. There's this little web app at Anyways, that's another story. Great work tommie, kudos to you :) |
This is probably just a side note, as subs for localpart are not here to stay. But they're too big apparently.
|
Yay, milestone! Okay, so if I'd expect other OIDC providers to work as well, then. The TODO for doing the But I think we should get the current code through review first. Less code is easier to review... |
That's strange. It looks like that's a function to generate a next higher numeric ID: https://github.com/matrix-org/dendrite/blob/main/userapi/storage/postgres/accounts_table.go#L67 const selectNewNumericLocalpartSQL = "" +
"SELECT COALESCE(MAX(localpart::integer), 0) FROM account_accounts WHERE localpart ~ '^[0-9]*$'" But combined with this comment: https://github.com/matrix-org/dendrite/blob/main/clientapi/routing/register.go#L555 // Don't allow numeric usernames less than MAX_INT64. Makes me think this is a Dendrite bug. It either shouldn't allow all-number localparts, or the MAX query should quietly ignore numbers that are too large. The code is used for guest accounts and when there's no requested localpart in registration. |
It makes more sense to base provider defaults on brand. Type is not 1:1 to brand. Splits apart OIDC and OAuth2 to match actual specs.
The issue happens after completing the SSO flow, aka after I have returned from my IdP to Cinny. |
In that case. Cinny sets the redirect URL to be the reg/login page: https://github.com/cinnyapp/cinny/blob/dev/src/client/action/auth.js#L18 On redirect, we end up with a This causes Cinny to run perform The app is supposed to instantiate The access token is set here: https://github.com/cinnyapp/cinny/blob/dev/src/client/action/auth.js#L52 If the access token is missing, we return to |
This fork don't work with openid connect, because clientapi/auth/oauth2.go still use OAuth2, not oidc and the config validation prevents setting of oAuth2. |
Sorry, I don't understand what's wrong. What configuration is rejected in validation? |
I'm using OpenID Connect perfectly fine. :) |
Clientid and client secret don't work. |
Oh, I take that back. The fields seem to be empty for client_id despite them being in the right place in config which happened after the config structure was changed. |
Thanks for the clarification. Yepp, I forgot to update the reading code when rearranging the config structure. Updated and merged from main. |
Android matrix clients use a custom redirect url (element uses element://connect and fluffychat uses fluffychat.im://login) which cause an error on the server when trying to login using OIDC. We found out that dendrite tries to parse the redirect url using url.parse, which fails on these custom urls. After commenting out the corresponding code in clientapi/routing/sso.go, lines 61 through 71, the error did not appear and login worked. |
Thanks for the report. If I play with those two URLs, it seems they should pass: https://go.dev/play/p/MqHeaM1yt9v Is it failing with URL parse failure, or the second if-body? Please also make sure you use the latest revision. The original didn't allow |
After pulling the new changes over (specifically the Docker changed made upstream), I'm not able to create a new container so not able to test unfortunately. :( |
It is actually failing in the secord if-body because ru.Path is empty. |
We recently updated our contributing guidelines. This PR is being closed because it isn't a feature we want to maintain going forwards. If you need this feature, it is possible to have a sidecar process handle registration, which upon success registers an account on Dendrite. When we have more bandwidth as a team, we would be very interested in supporting this natively. |
I think quite a number of people would consider this to be useful. What's your stance on a PAM-y approach where other authentication methods can be "plugged in" by providing a binary that acts as an interface between dendrite and whatever other service? I think that would be the easiest™ approach to allow OpenID support without massively increasing the burden on you to actually maintain it. |
Hmm, that's an interesting path forward. If Dendrite just implemented "trusted" authentication, we could write proxies that do all forms of authentication. The proxy just passes on an |
Something like https://dexidp.io/ which transfer oidc to LDAP, saml and so on? |
In a way… after all Matrix has some rather specific requirements which might not be available for all possible backends. So I think some (i.e. probably a lot) architecture work will still be necessary. |
This is a first happy case. There's nowhere for the user to select a localpart, which makes it a bit useless in production. If the identity provider doesn't provide a
preferred_username
in the userinfo endpoint, we fall back to the normal "highest numeric localpart" as used in registration. An overview of HTML pages that need to be served by Dendrite to cover Synapse usecases is inconfig/sso.py
.A further improvement is to add a configuration option to limit who can use SSO. E.g. tying it to a custom domain using
email
andemail_verified
. After a cursory glance, I don't think Synapse has this ability, so it's a low priority.Tested with tommie/complement@e08054c
Clarifications from comments
/login
, not/register
. Supporting user-interactive authentication requires serving HTML pages, a big (or potentially contentious) task. A previous PR implementedm.login.token
as a prerequisite for this PR; supporting SSO is a multi-PR endeavour.TODOs from comments
oauth2
andoidc
config parameters when usingoidc
. Infertype
from the existence of either.default_provider
.claims_supported
, since it's speced as a partial list, and completely pointless.path
to be non-empty in client-provided URLs.Investigate if/register
(or all) requests need to return some Unimplemented error code while user-interactive is unsupported. Cinny seems to never stop trying to register.Signed-off-by:
Tommie Gannert <[email protected]>