oauthenticator
oauthenticator copied to clipboard
Implement MultiOAuthenticator
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.
Does MultiOAuthenticator only work with OAuthenticator derived authenticators, or would it work with others?
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:
- The local authenticators have no "name" to show on the button so we could make use of the
login_serviceconfiguration to give them one to generate the button in the custom html. But thelogin.htmltemplate makes use oflogin_serviceto 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. - 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.
- Following point 2, the
authenticator_login_urlgenerated for the template will be wrong as the authenticator has no idea of theurl_scopeand 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 ?
Small ping :-)
Another ping. This is useful.
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.
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.
Hello, Any updates or plan to integrate this feature ? \cc @consideRatio and @sgaist
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, 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.
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.
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.
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.
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 👍
@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 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.
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.