SSO Support
Implements https://github.com/LemmyNet/lemmy/issues/2930.
This PR is based on this previous PR by @thepaperpilot.
Related PRs:
- https://github.com/LemmyNet/lemmy-js-client/pull/297
- https://github.com/LemmyNet/lemmy-ui/pull/2578
We noticed that the original PR is outdated and has a lot of conflicts with the recent changes. We tried to keep the previous commits whenever possible (in lemmy-js-client and lemmy-ui).
How it works?
- Admins can configure external OIDC providers from within the admin settings.
- Once an OIDC provider is configured, users will be able to Sign In / Sign Up using external OIDC providers.
Available Configuration
- The usual OIDC endpoints
- auto_verify_email: When enabled, users signing up using OIDC won't need to go through email verification.
- ~~auto_approve_application: When enabled, users signing up using OIDC won't need manual approval even if applications are required.~~
- account_linking_enabled: When enabled, users attempting with sign up with OIDC using an existing user email would link the OIDC account to the existing user.
Disclaimer This is our first ever rust contribution.
Who we are? Why are we contributing to Lemmy?
Privacy Portal is an OIDC provider and an email aliasing service focused on privacy. We have decided to contribute to select open source projects that empower Free Speech online. Our OIDC provider services are currently offered free of charge. In the future, we will have a generous free plan that will cover most deployments. Using Privacy Portal as your OIDC provider offers your users great privacy benefits. User emails will automatically get replaced by single-purpose Privacy Aliases during sign up. Users will be able to enter any name (to be used as username). Users can benefit from email encryption and much more.
Wonderful! We’re also building an OIDC provider for indies, so this is a very welcome development 😊
I wasn’t able to find it in your PR; are you implementing PKCE grant flow? It’s more secure, and some identity providers (like ours) rely on it to function.
Prior art in fediverse:
- https://github.com/mastodon/mastodon/pull/30329
- https://github.com/superseriousbusiness/gotosocial/issues/2225
@erlend-sh This PR doesn't support PKCE grant flow yet but, once it's merged, adding PKCE support should be a small change. We'll try to make some time to add it in a separate PR.
Could you give some instructions how we can test this functionality? Maybe by writing some documentation (that will be necessary anyway).
@Nutomic we'll write some docs for users but given that local testing is slightly more complicated, here are the steps to test it:
1- You will need the changes from these 3 PRs locally:
- https://github.com/LemmyNet/lemmy/pull/4881
- https://github.com/LemmyNet/lemmy-js-client/pull/297
- https://github.com/LemmyNet/lemmy-ui/pull/2578
2- The lemmy-ui changes require the latest version of lemmy-js-client (the PR does not include this version yet since it requires publishing to npm. You will need to add it manually).
cd $LEMMY_JS_CLIENT_DIR && pnpm run prepare
cd $LEMMY_UI_DIR pnpm add $LEMMY_JS_CLIENT_DIR
3- Run the DB migrations diesel migration run --database-url $LEMMY_DATABASE_URL
4- Now you should be able to start lemmy and lemmy-ui
5- Sign In to Lemmy as admin and go to the admin settings page: http://localhost:1234/admin
6- Enable "oauth_registration" under the "Site" tab to allow users to Sign Up using OAUTH
7- Under the "authentication" tab you will need to add an OIDC provider configuration.
- Most fields in this configuration are provided to you by the OIDC Provider including the "oauth_issuer", "oauth_authorization_endpoint", "oauth_token_endpoint", "oauth_userinfo_endpoint".
- You will need to find out which scopes are needed by the provider in question in order to get access to the user_id, name and email. The scopes will need to be set under "oauth_scopes" and you will need to fill the "oauth_id_claim" and "oauth_name_claim" fields to tell Lemmy the name of the properties containing the user_id and the user name as returned by your OIDC provider.
- To simplify this step we added a preset configuration to Lemmy-ui for the Privacy Portal OIDC provider. Additional preset providers can be added at any time by opening Pull Requests.
8- The remaining fields "oauth_client_id" and "oauth_client_secret" are instance specific and require you to create an account with your preferred OIDC provider. With Privacy Portal, you can create a free account and test this setup like the following:
- Sign up at https://app.privacyportal.org
- Go to "Developer Settings"
- Create a "New Application"
- Register the application with the following information
{ "Name": "Lemmy Test", "Homepage URL": "http://localhost:1234", "Callback URL": "http://localhost:1234/oauth/callback" } - Under Credentials, you should now get a "client_id" that you can use on Lemmy-ui to fill the "oauth_client_id" field.
- Also under Credentials, tap on "Generate Secret" to get a secret that you can use to fill the "oauth_client_secret" in Lemmy-ui.
9- Now you should have all the fields filled in your configuration, click "save" and sign out from the admin account. 10- Go to the Lemmy Login page, you should now see the SSO button to login with your configured provider.
@dessalines @dullbananas we've addressed most of the issues raised. Is there anything we're missing? Thanks!
Also there's this clippy error: https://woodpecker.join-lemmy.org/repos/129/pipeline/8173/17
@privacyguard just a small note: PKCE is now recommended for all oauth applications, due to authorization code injection attacks: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-security-topics#section-4.5
If this is intended for API client usage (I'm not sure), then you may want to adopt this new draft: https://drafts.aaronpk.com/draft-parecki-oauth-client-id-metadata-document/draft-parecki-oauth-client-id-metadata-document.html
Which allows clients to identify by an URI to a public document describing the client, rather than requiring dynamic client registration.
@ThisIsMissEm is that something that we could add on later, or better to do now? If so we could open an issue for it.
@ThisIsMissEm is that something that we could add on later, or better to do now? If so we could open an issue for it.
Both can be added later on, though I'd really recommend implementing PKCE soon, as it's really not that hard to implement overall (it's just storing a value with an access grant and comparing the sha256 of that value with the supplied value when exchanging an authorization code for an access token)
For the I-D that I'm working on, that's intended mostly for public clients on authorization servers, so, like, alternative frontends that sign-in to lemmy through oauth or API Applications; I'm not sure how your system is designed, so I can't really offer further guidance.
This is in a pretty good state, just needs some feedback from @Nutomic and @phiresky . We'll try to get this in 0.20.0
@phiresky does the PR look good to you or is there anything remaining that you think needs fixing on our side?
BTW we didn't resolve conflicts since the PR won't be merged immediately so conflicts will continue popping up until 0.20.0.
Is there any timeline currently planned for the 0.20.0 release?
Thank you all for your feedback and reviews! It looks like, except for merge conflicts, this PR is in a good state for 0.20.0. We're looking forward to getting it merged for Lemmy users to enjoy.
There were some extra steps I needed to do to get the dev setup working, also I wanted to use docker. I took some notes here (I copy-pasted a good amount from @privacyguard's previous comment): https://gist.github.com/gwbischof/ea41a74410b8fa890f148b5d45310513
The "Login with Privacy Portal" Button didn't work on Chrome, but it did work with Safari.
@gwbischof Thanks for documenting the docker setup! Concerning the "Login with Privacy Portal" button not working on Chrome, do you happen to have any logs? Which version of Chrome are you using?
@privacyguard I just tried again "Login with Privacy Portal" button again on Chome, and its working now. So, there is probably nothing to fix :)
This has been sitting for a while, and we might as well merge this once those are addressed. It'll probably need to be tweaked and fixed in a test environment like voyager.lemmy.ml anyway, so the sooner we can merge and find those bugs, the better.
@dessalines We were waiting to see when 0.20.0 is planned to address the remaining issues before the release. But we'd rather do a final push and get everything completed and merged in one shot rather than keep switching back and forth to this PR. If this can be merged as soon as all the issues are resolved, we could probably get it done over the weekend.
We are merging breaking changes to main branch now, so this can be merged as soon as everything is adressed.
@Nutomic @dessalines Yesterday we rebased this branch, resolved all conflicts, and addressed the remaining issues raised. Please let us know if there's anything else remaining or whether this can be merged. Thanks!
Good job, thank you!
@privacyguard any chance of adding PKCE support?