oauthenticator icon indicating copy to clipboard operation
oauthenticator copied to clipboard

Implement MultiOAuthenticator

Open sgaist opened this issue 4 years ago • 16 comments

This authenticator allows to use several different services to authenticate to one instance of JupyterHub.

The code is based on the suggested implementation that can be found on #136 and more specifically https://github.com/jupyterhub/oauthenticator/issues/136#issuecomment-749931724.

Due to the merge of https://github.com/jupyterhub/jupyterhub/pull/3315, the support for showing multiple links is already supported.

This is the first step as discussed in this JupyterHub discourse thread.

sgaist avatar Sep 23 '21 15:09 sgaist

Does MultiOAuthenticator only work with OAuthenticator derived authenticators, or would it work with others?

manics avatar Sep 23 '21 16:09 manics

It's a good point you have here. I haven't thought about them.

As it is MultiOAuthenticator handles any authenticator that implements the Authenticator interface. It currently does not make use of any implementation specific details of OAuthenticator.

That said, there are some issues to address for the "local" authenticators:

  1. The local authenticators have no "name" to show on the button so we could make use of the login_service configuration to give them one to generate the button in the custom html. But the login.html template makes use of login_service to determine whether it should render a button or the login form so when we get there it will render a single button that proposes to login with the authenticator selected and then back to the list of buttons when clicked.
  2. The next issue is the login url used for the post action which comes from the settings rather than using the one from the authenticator.
  3. Following point 2, the authenticator_login_url generated for the template will be wrong as the authenticator has no idea of the url_scope and thus will return an invalid value.

For number 2, a change in the login.html template to use authenticator_login_url seems to be enough.

For number 3, I have tested an approach using a mixin class to overwrite login_url, logout_url and get_handlers. It is used to dynamically create a subclasses that is configured with the scope and appends it to the base_url. This simplifies the rest of the code a bit as well.

For number 1, it's a bit more tricky. One possible solution could be to handle a MultiAuthenticator specific "service name" configuration parameter that could be used in place of login_service when generating the buttons. This would allow to not modify the base class. We could also document the requirement to create a simple subclass adding that name.

Should I push the proof of concept on top of this merge request so you can compare the two implementation ?

sgaist avatar Sep 24 '21 12:09 sgaist

Small ping :-)

sgaist avatar Jan 21 '22 16:01 sgaist

Another ping. This is useful.

abdelq avatar Feb 28 '22 08:02 abdelq

This is very useful! However, as far as I can tell, it doesn't seem to have any means of handling username collisions. What happens when one person's username on one service is the same as someone else's username on another service? Some sort of prefix, or other configurable transform, may be needed for the resulting JupyterHub username.

tmtabor avatar May 17 '22 17:05 tmtabor

This is very useful! However, as far as I can tell, it doesn't seem to have any means of handling username collisions. What happens when one person's username on one service is the same as someone else's username on another service? Some sort of prefix, or other configurable transform, may be needed for the resulting JupyterHub username.

Thanks !

I think that, from an architecture point of view, it is something that should be handled on the JupyterHub side since it's there that the user management happens. The role of the authenticator is to handle the authentication process but not the user management.

sgaist avatar Jun 14 '22 14:06 sgaist

Hello, Any updates or plan to integrate this feature ? \cc @consideRatio and @sgaist

Ph0tonic avatar Jun 26 '23 06:06 Ph0tonic

Hi, After looking at this proposition, I wonder whether this code should be incorporated into jupyterhub. As it might be used by other authenticators not provided in this library. \cc @sgaist and @manics

Ph0tonic avatar Jul 11 '23 13:07 Ph0tonic

@Ph0tonic, while it was originally geared towards OAuth providers, it something that could indeed live in JupyterHub since it also supports other providers as it is not tied to the implementations of OAuth authenticators.

Maybe @minrk might want to also weigh in.

sgaist avatar Jul 12 '23 13:07 sgaist

Hi, any update on this PR ? Should we make a PR in jupyterhub ? We could manage conflicting users in a different way if it was managed by jupyterhub. For example, by configuring an authenticator id and by storing it with the username in the db.

Ph0tonic avatar Aug 02 '23 08:08 Ph0tonic

My vote is to put this in a new repository/package that has oauthenticator as a dependency, collaboratively work on it there, test it in production, and then review whether some or all of it should be brought into JupyterHub.

manics avatar Aug 02 '23 08:08 manics

Hi guys,

Sorry for the late reply. The plan sounds good to me.

@manics would that repo be under the jupyterhub organisation or my own space ?

I have done some preparation work taking my fork of oauthenticator apart to keep only the MultiAuthenticator class to follow the same project structure. The only part that might have some issue is the GitHub pipeline as I haven't used them yet actively.

sgaist avatar Sep 22 '23 16:09 sgaist

Hi guys,

Sorry for the late reply. The plan sounds good to me.

@manics would that repo be under the jupyterhub organisation or my own space ?

I have done some preparation work taking my fork of oauthenticator apart to keep only the MultiAuthenticator class to follow the same project structure. The only part that might have some issue is the GitHub pipeline as I haven't used them yet actively.

I am available to help and test, let me know once you have a new repo 👍

Ph0tonic avatar Sep 23 '23 11:09 Ph0tonic

@sgaist Thanks for working on this! Starting with your own personal repo will be the easiest way for now, and we can transfer it later if we want. Personally I think something jupyterhub-contrib would be a good home but that's still being discussed https://github.com/jupyterhub/team-compass/issues/519

manics avatar Sep 24 '23 20:09 manics

@manics You're welcome !

jupyterhub-contrib sounds good. I was thinking about something similar so it's great to see the idea was already floating around.

I'll create the repo during the week.

sgaist avatar Sep 24 '23 20:09 sgaist

Hi,

As promised: https://github.com/idiap/multiauthenticator

@Ph0tonic: thanks for the reviews and suggestions done here, I integrated your scope fixes already. And I have found a simpler way for the configuration issue. Can you test that ?

Can you also open an issue over there to discuss the username collision problem ? I think there might be two options here:

  • Yours which ensures that each backend provides a unique user name but with the drawback of having a "scoped" username shown.
  • "Merged users" but this one is tricky as you cannot be sure that every user uses the same username on multiple platforms. Also this would require changes to the user handling in JupyterHub itself.

sgaist avatar Oct 02 '23 15:10 sgaist