Giving the User the chance to choose an Authenticator

I would like to offer my users the chance to choose how they want to log on. Specifically I would like to give them the opportunity to login with a username-password combo as well as Google OAuth.
A user can then choose to use OAuth or their username-password.

The reason being that all my students will use OAuth through their institution mail address, while my co-instructors don’t necessarily have the institution mail address and would rather have a username-password system.

I have tried creating a class that inherits both the FirstUseAuthenticator and GoogleOAuthenticator but that ended up simply having one of the two dominant and the other functionality ignored because of this: https://docs.python.org/3/tutorial/classes.html#multiple-inheritance
I tried hacking the login screen, clean code be damned but that was also to no avail.

Any ideas or solutions are very much welcome.

1 Like

OK.
It took some serious trial and error but I was able to figure it out on my own. Turns out it’s quite simple.

I created a repo on github to show how I did it: https://github.com/Rayal/jupyter-multi-authenticator

I still went with the multiple inheritances, but explicitly returned from one or the other superclass based on what was supposed to work at the time.

1 Like

Hmm.
I just realized that there is a fundamental problem with the solution, as it is at present. I have a solution, but it will take some time before I push the changes. I’m writing it here so that anyone else going down my path understands the situation.

Yes, my solution allows for two authenticators to run at the same time. There is however, some unexpected behaviour when authenticating yourself with the system that DID NOT create your user. As a specific example, using the Google OAuthenticator I create a user with the e-mail example@gmail.com. They get assigned the Jupyterhub username “example”.
Knowing this, I can now login to the user with the Jupyterhub username “example” using the FirstUseAuthenticator without needing to type in a password, because FUA checks the database for a password and if there is none, it accepts a login attempt with no password.
A quick fix (that doesn’t fix the fundamental issue) is to edit the FUA code to make it automatically fail all login attempts without a password.