Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom authentication for workshops #4

Closed
craig-willis opened this issue Apr 12, 2018 · 9 comments
Closed

Custom authentication for workshops #4

craig-willis opened this issue Apr 12, 2018 · 9 comments

Comments

@craig-willis
Copy link
Contributor

craig-willis commented Apr 12, 2018

Exploring authentication methods for workshops. ESIP authentication via Wordpress may not be possible. Oauth is considered too broad for ESIP. Per recommendation from the Jupyterhub community (via Gitter),

if you are doing pre-defined temporary user accounts you could do a custom authenticator that is as simple as a Dictionary Authenticator... I would probably build the dictionary dynamically with that many users.

from tornado import gen
from traitlets import Dict
from jupyterhub.auth import Authenticator


class DictAuthenticator(Authenticator):

    passwords = Dict(
        {“user1": "password", “user2": "password"},
        config=True
    )

    @gen.coroutine
    def authenticate(self, handler, data):
        if self.passwords.get(data['username']) == data['password']:
            return data['username']

This can be done with a custom hub image or by overriding the config.

You could do a custom image - but you could also include this code in the config.yaml file that is used with the helm install/update command. It would be in the hub section

hub:
  extraConfig: |
    from tornado import gen
    from traitlets import Dict
    from jupyterhub.auth import Authenticator

    class DictAuthenticator(Authenticator):

        passwords = Dict(
            {“user1": "password", “user2": "password”}, 
            config=True
        )

        @gen.coroutine
        def authenticate(self, handler, data):
            if self.passwords.get(data['username']) == data['password']:
                return data['username’]

The custom hub image is as easy as extending the Docker image:

 FROM jupyterhub/k8s-hub:v0.6
...
@craig-willis
Copy link
Contributor Author

@scgordon You mentioned that ESIP uses Drupal? Looking at http://www.esipfed.org/ it appears to use WordPress for authentication. If this is the case, it may be possible to integrate with the WordPress API for authentication via custom authenticator as above.

@jreadey
Copy link
Collaborator

jreadey commented Apr 12, 2018

@craig-willis - Thanks for the example of using Authenticator - I was wondering if it was possible to do that via config vs a custom Hub image.

@scgordon
Copy link
Collaborator

That's what Annie reported back from the webmaster.

Relevant email:

There isn't currently any open standards-based shared login system for the ESIP credentials used to log in to the Commons and Wiki etc. That is, all the ESIP account login credentials are stored internally to Drupal in a way that's not easy to share across other applications. The shared Commons/Wiki login uses a custom integration between Drupal and MediaWiki that was developed by UAH.

We could use the Commons (Drupal) instance as an OAuth 2 provider so the login credentials could immediately be shared across other applications (eg. https://www.drupal.org/node/1938218), but this would require setup and testing time - I'd allow 2-5 hours (but it could be more if complexities come up). Also, the system would go away whenever the Drupal 7 instance needs to be retired, so it could work for a few years, but it's not the best long-term solution.

Alternatively, we could set up an independent OAuth2 server separate from Drupal, and use that service to handle logins across a range of tools used by ESIP - including Drupal, MediaWiki, Wordpress, Jupyter etc. This would be a better long term solution, but we would either have to start accounts from scratch or find a way to import the current accounts from Drupal into the OAuth server. You can either set up and host an OAuth server yourself (can estimate if you like), or use a hosted service such as http://oauth.io (but pricing is not clear).

Hope that helps clarify the current situation and some options for the future.

Thanks, David

@craig-willis
Copy link
Contributor Author

Thanks, @scgordon. It may not be worth pursuing, but if Drupal is the primary identity store it might be possible to hit the REST endpoint directly (https://www.drupal.org/node/910598). I wasn't able to do this in a quick test, so it's possible that something would need to be enabled on the server side.

@dbassendine
Copy link

Hi everyone,

If it helps, we can expose the user info via a REST endpoint that returns JSON (or other format). I would need to install and enable the Services module, then configure the endpoint and authentication. Out of the box you can retrieve individual users based on their (Drupal) user id, but for this it looks like we would need to return a list of users that meet certain criteria (eg/ not including accounts which haven't passed authentication checks) - for which we would also need a intermediary "view" (query builder) passed to the endpoint.

Let me know what exactly you would need returned from the endpoint, and I'll take a look at what it would take to set up - though it looks less complex that the OAuth setup.

@scgordon
Copy link
Collaborator

David, thanks for weighing in. What you're proposing allows people to use their regular passwords and user names to login, but we wouldn't be in a single sign on situation, right?

What I'm getting at is people would need to know their password, which might result in a lot of people trying to reset their password during the workshops

So I'm wondering if it's just simpler for us and the users to have slips of paper with credentials for the week slipped into their badges and readdress this when we know if it'll get support after August...

@dbassendine
Copy link

Well, this was mainly in response to the approach in the first comment, where you have an independent system (such as a Dictionary Authenticator) handling the authentication, but that system needs access to user credentials from Drupal. The REST endpoint wouldn't stand up on its own as an authentication solution. I'm not really familiar with the Dictionary Authentication approach, so I can't comment productively on that - I assume, yes people would need to know their password.

The quickest and most straightforward technical approach would probably be to spend a couple of hours setting up Drupal as an OAuth provider, and test out to see how well that works (I haven't personally used that system before, so I'm not sure of the "unknown unknowns" as it were!). Or the low tech badge solution seems smart too, if it works for you :)

@betatim
Copy link

betatim commented May 9, 2018

The hash-authenticator has worked well for me in the past. It computes the password based on a salt and the user name. So if you know all the usernames ahead of time you can automate the generation of the username <-> password list to bring along to the workshop.

edit: seems development has moved to https://github.com/thedataincubator/jupyterhub-hashauthenticator

@craig-willis
Copy link
Contributor Author

For the initial iteration, we're using the DictionaryAuthenticator with a static list of pre-generated credentials. I've pushed the sample configuration https://github.com/nds-org/esiphub/blob/master/jupyterhub/config_jupyterhub.yaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants