Authentication with kerberos / AD

I set up JupyterHub for our data science team. Our firm uses Active Directory for authentication and I wanted to leverage that. I was unable to get the Kerberos authentication method that is linked from the JupyterHub github page to work. However, I was able to cobble together something that works for me so I thought I’d share it.

The basic idea is to run kinit user@AD.DOMAIN.COM and pipe in the password during the authenticate call of my custom Authenticator class, saving the resulting credential class file to a volume that is shared between the hub container and the spawned containers.

Two prerequisites are needed. First the hub container needs to install the packages, and possess the krb5.config necessary to run kinit. Second, the resulting kerberos credential cache file needs to be stored in a place accessible to the spawned user container, for that I used a shared volume.

With that background, the following code is my custom Authenticator which I defined inline in the jupyterhub_config.py file:

class KDBAuthenticator(Authenticator):

    @gen.coroutine
    def authenticate(self, handler, data):

        user = data.get('username', 'None').lower()
        self.log.info('Authenticating: ' + user)
        pwrd = data['password']

        realm = 'OUR.REALM.COM'
        kinit = '/usr/bin/kinit'
        krbcc = '/srv/jupyterlab/krb5cc_%s' % (user,) # This path is on the shared volume
        kuser = '%s@%s' % (user, realm)

        kinit_args = [kinit, kuser, '-c', krbcc]
        pecho_args = ['echo', '-n', pwrd]
        self.log.info('Running: ' + ' '.join(kinit_args))

        pecho = Popen(pecho_args, stdout=PIPE)
        kinit = Popen(kinit_args, stdin=pecho.stdout, stdout=PIPE, stderr=PIPE)
        
        self.log.info(kinit.communicate())
        ans = None
        if os.path.isfile(krbcc):
            os.chmod(krbcc, 0o666)        
            ans = user
        return ans       

There are security implications of deploying this that you may or may not be comfortable with.

I hope this helps someone else trying to do the same. If anyone has questions or comments feel free to reach out.

Matt

4 Likes

Cool and thanks for sharing the information. This might be an interesting scenario for us to incorporate with JupyerHub and Jupyter Enterprise Gateway integration.

@kevin-bates

Can not work for me. I install jupyterhub with conda. Can you help me?

From a security perspective I don’t think anybody should implement this solution - it is not wise to send password (or any other secret) to other programs like that.

The password will be leaked in the process list (ps) which is bad.

1 Like