Continuing the discussion from Two-factor local login option:
Hey everyone, I’m planning to look into tackling two factor authentication very soon. This would allow a user to secure a discourse account by requiring a one time password to be generated via Google Authenticator/Authy.
Here’s a proposal to how two factor authentication through google authenticator flow would work:
The user would log in as usual. After a user logs in, the system checks whether or not the user has two factor enabled. If two factor is enabled, a second login prompt would be shown, asking a user for their one time password.
A user will be able to enable two factor authentication in the user preferences.
Enabling would bring up a QR code, that would need to be confirmed with a successful one time password.
If a user is unable to scan the QR code, or prefers to type in the key manually, they are able to view the key via the “enter the key manually link”.
Once Discourse confirms that you can successfully generate codes, it will require future local logins to be completed with an authorization key.
Some implementation details:
If a user attempts to disable a 2fa key, it will ask for a token before the key is disabled.
If a user re-enabled 2-factor, the 2fa key will be re-generated. This allows a 2-factor “reset” in the event of a stolen key. However, any authenticator would have to be re-set up, which could be a pain if you have multiple devices/apps that you would like to set up with the authenticator.
I really like the idea of being able to generate some kind of backup key codes, in the even that you are parted with your authenticator app somehow, or perhaps gets disabled when a user resets a password. The latter would follow the general Discourse account handling that “if you have access to the email, you have access to Discourse”. (Backup codes tabled for v2.)
I also really like the idea of being able to set up two factor through texts later, possibly by using a twilio API.
Edit: not happening, as NIST recommends against this.
As a first step, I’m looking to tackle the basic flow described above to get Discourse working with Google Authenticator, and expand out from there. I’m looking at adding the gems
rotp for the code generation + checking, and
rqrcode for processing QR codes.
Admins and Moderators will be able to disable 2fa for other users.
Any feedback, requests, or security concerns about this proposal are welcome - Let me know what you think!