Wingysam / Christmas-Community

Christmas lists for families
GNU Affero General Public License v3.0
234 stars 41 forks source link

TOTP-based MFA #26

Open Wingysam opened 1 year ago

Wingysam commented 1 year ago

Christmas Community should allow users to sign in with TOTP 2FA codes.

Wingysam commented 1 year ago

Depends on #23

bsiddans commented 10 months ago

A possible alternative option to consider, rather than adding to the existing auth options, could be to add support for using headers set by a proxy for authentication. For example, put the app behind a proxy like Caddy, and have Caddy send users to something like Authelia for auth. If successful, Authelia sets the Remote-User header with the username, Caddy passes it to the application, user is allowed in and identified. I've got a version of this working but it's rough and would need some work to be merged.

This could make things simpler in terms of outsourcing authentication to another app (like Authelia, which already has TOTP and Webauthn built-in), but it would make deployment more complex (you'd need a proxy, Authelia plus it's supporting services, plus this project). But if it was a configurable option, it would be avoidable for users where password is all that is required.

I can look at trying to work something up and send a PR if it's of interest? I did it using passport-reverseproxy however, so if you're looking to remove Passport per #25, or want to go a different direction, happy to skip it.

Wingysam commented 9 months ago

What exactly does Authelia pass as a header? And how does user management work with it?

004a commented 9 months ago

Authentik will pass the header X-Authentik-Username with the authenticated user's name. When the app receives that header, it will auto login with the user in the value and create the user if it doesn't already exist, bypassing the app's default login form.

bsiddans commented 9 months ago

What exactly does Authelia pass as a header? And how does user management work with it?

Authelia will pass Remote-User with a username but as @004a mentioned different solutions might pass something else.

In terms of user management, to add a user, the workflow would be something like this:

  1. Add a user account to whatever Authelia is using as a backend for authentication. I use lldap, so I add a user to that.
  2. Add a user to Christmas-Community via the admin page. As part of this process I manually click the link to confirm the account, the link may not be needed in this scenario. The password that the user is given as part of this process isn't actually used, since the header identifies them not the password.
  3. The user manages their password etc through Authelia, or whatever other frontend is used. In my case, I send users to Authelia, they setup their password and 2FA there. Authelia handles forgotten passwords etc itself.

Basically, the only part of user management that remains is adding a user account to Christmas-Community so its in the database. I guess it would be possible to remove the need to do that somehow but that's more complicated than I've needed to go into.

Wingysam commented 9 months ago

Okay, so I add an env variable that will check Remote-User and X-Authentik-Username, then automatically create/log in that user on every request?

004a commented 9 months ago

Okay, so I add an env variable that will check Remote-User and X-Authentik-Username, then automatically create/log in that user on every request?

Works for me!