nds-org / esiphub

ESIPhub pilot materials
0 stars 4 forks source link

Custom authentication for workshops #4

Closed craig-willis closed 6 years ago

craig-willis commented 6 years ago

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 commented 6 years ago

@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 commented 6 years ago

@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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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 commented 6 years ago

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