openwebwork / webwork2

Course management front end for WeBWorK
http://webwork.maa.org/wiki/Main_Page
Other
143 stars 165 forks source link

Add two factor authentication. #2335

Closed drgrice1 closed 6 months ago

drgrice1 commented 6 months ago

This uses the TOTP (time-based one-time password) protocol. Any authenticator app on a mobile device that supports this protocol can be used (for example, Google Authenticator, Microsoft Authenticator, Twilio Authy, etc.).

Whether this is enabled or not is controlled by new course environment variable $twoFA{enabled}. If that is set to 0, then two factor authentication is disabled for all courses. If that is 1 (the default), then two factor authentication is enabled for all courses that use password authentication (of course two factor authentication does not apply to courses that use external authentication methods like LTI, CAS, Shibboleth, etc.). If that is a string course name like 'admin', then two factor authentication is enabled only for that course. If that is an array of string course names, then two factor authentication is enabled only for those courses listed. This can also be set in a course's course.conf file. Note that only the values of 0 and 1 make sense there.

There are two methods that can be used to setup two factor authentication when a user signs in for the first time. The setup information can be emailed to the user, or can be directly displayed in the browser on the next page that is shown after password verification succeeds.

This is controlled by the new course environment variable $twoFA{email_sender}. If that is set, then the email approach will be used. In this case, after a user signs in and the password is verified, the user will be sent an email containing a QR code and instructions on how to set up a OTP generator app. This is probably a more secure way to set up two factor authentication, as it ensures the user setting it up is the correct user. Note that if a user does not have an email address, then the browser method below will be used as a fallback.

If $twoFA{email_sender} is not set, then after a user signs in and the password is verified, the QR code, OTP link, and instructions will be displayed directly on the page in the browser. This is potentially less secure because a hacker could guess a username and password before a user has setup two factor authentication (particularly if the username and password are initially the same), and then the hacker would gain access to that user's account, and the actual user would be locked out. Note that you will need to use this option if your server can not send emails. Also note that no-reply addresses may be blocked by the email server or marked as spam. So it may be better to find a valid email address to use for this.

This requires a new database column otp_secret that was added to the password table (for lack of a better place to put it).

There is a new wwsh script (bin/reset2fa) that can be used to reset two factor authentication for a user if a user somehow loses their setup in an authentactor app on their mobile device. That just removes the OTP secret from the database. This means that the user will need to go through the two factor authentication setup process again. To use it execute: wwsh courseID /opt/webwork/webwork2/bin/reset2fa userID. Multiple user ids can be listed if you want to reset more than one user at a time. Note that this script is the only way that an admin user can reset their own two factor authentication (and there should never be another way for admin users to do this for themselves). Perhaps a page in the admin course could be added for resetting this for instructors.

A form has been added to the Accounts Manager for resetting two factor authentication for students. This form does not allow the user to reset their own two factor authentication secret, but that of other users at equal or lesser permission level to their own. Note that in the admin course if there are multiple admin users, then one admin user can reset two factor authentication for another. Also there is some clean up and issue fixes in the htdocs/js/UserList/userlist.js file with form validation. The "change" event handler was being added multiple times to the users list table. More clean up is needed though (with this and the other pages with action forms). There is a lot of redundancy with this form validation implementation.

There is an option to skip two factor authentication on trusted devices. A checkbox is on the two factor verification page. If that is checked, then a signed cookie (separate from the session cookie) is set. If that cookie is set, then two factor verification is skipped for sign in attempts.

This builds on #2333 and #2334, and is the final part of the authentication system revamp.

drgrice1 commented 6 months ago

Both Fedora 39 and RHEL 8 have GD::Barcode version 1.15 packaged. In both cases I had to uninstall the packaged version and install from CPAN (version 2.0). With the CPAN version it works on both.

We will just need to tell those using Fedora or RHEL to use the CPAN version. That is not too big of a deal. It wouldn't be the first time we have instructed administrators to use a CPAN version over a distribution package.

I did a quick test with both the Microsoft and Google Authenticator Apps and was able to log in with 2FA. One observation: The name of the entry in the authenticator app is the course name. How about prefixing this with one of the following to make it more descriptive:

* The name of the server
* A string that is set in configuration, which could default to either "WeBWorK" or the `$server_root_url`

I knew this would come up. I don't care what we go with. Does anyone have a preference? In any case it should still contain the course ID, but what should it be prefixed with?

dlglin commented 6 months ago

We will just need to tell those using Fedora or RHEL to use the CPAN version. That is not too big of a deal. It wouldn't be the first time we have instructed administrators to use a CPAN version over a distribution package.

There are already several packages that have a minimum version in check_modules.pl. Should we just say version 2.0 there?

drgrice1 commented 6 months ago

Well, the version on Ubuntu is 1.15. That version works fine (with the Ubuntu modifications).

drgrice1 commented 6 months ago

Another thing with the TOTP issuer (which is what is shown as the name of the entry in the authenticator app). How should this prefix (whatever we want for that) and the course id be put together? Should : be used to separate them perhaps?

drgrice1 commented 6 months ago

I set the issuer for the otpauth URL to be the absolute URL of the set_list route without https?://. So that will be your.server.edu/webwork2/course_id. This means for the Google Authenticator app the label will be your.server.edu/webwork/course_id: user_id.

Alex-Jordan commented 5 months ago

I'm wondering now if "Skip two factor verification on this device." should be something like "Skip two factor verification on this device in the future." The first time you are exposed to this, it's a little confusing. Like you could just check the box and skip this altogether.

drgrice1 commented 5 months ago

Yeah, that would be fine.