• Stars
    star
    206
  • Rank 190,504 (Top 4 %)
  • Language
    Python
  • License
    BSD 3-Clause "New...
  • Created almost 9 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

LDAP Authenticator Plugin for Jupyter

ldapauthenticator

Latest PyPI version Latest conda-forge version GitHub Workflow Status - Test Test coverage of code Issue tracking - GitHub Help forum - Discourse

Simple LDAP Authenticator Plugin for JupyterHub

Installation

You can install it from pip with:

pip install jupyterhub-ldapauthenticator

...or using conda with:

conda install -c conda-forge jupyterhub-ldapauthenticator

Logging people out

If you make any changes to JupyterHub's authentication setup that changes which group of users is allowed to login (such as changing allowed_groups or even just turning on LDAPAuthenticator), you must change the jupyterhub cookie secret, or users who were previously logged in and did not log out would continue to be able to log in!

You can do this by deleting the jupyterhub_cookie_secret file. Note that this will log out all users who are currently logged in.

Usage

You can enable this authenticator with the following lines in your jupyter_config.py:

c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'

Required configuration

At minimum, the following two configuration options must be set before the LDAP Authenticator can be used:

LDAPAuthenticator.server_address

Address of the LDAP Server to contact. Just use a bare hostname or IP, without a port name or protocol prefix.

LDAPAuthenticator.lookup_dn or LDAPAuthenticator.bind_dn_template

To authenticate a user we need the corresponding DN to bind against the LDAP server. The DN can be acquired by either:

  1. setting bind_dn_template, which is a list of string template used to generate the full DN for a user from the human readable username, or
  2. setting lookup_dn to True, which does a reverse lookup to obtain the user's DN. This is because ome LDAP servers, such as Active Directory, don't always bind with the true DN.
lookup_dn = False

If lookup_dn = False, then bind_dn_template is required to be a non-empty list of templates the users belong to. For example, if some of the users in your LDAP database have DN of the form uid=Yuvipanda,ou=people,dc=wikimedia,dc=org and some other users have DN like uid=Mike,ou=developers,dc=wikimedia,dc=org where Yuvipanda and Mike are the usernames, you would set this config item to be:

c.LDAPAuthenticator.bind_dn_template = [
    "uid={username},ou=people,dc=wikimedia,dc=org",
    "uid={username},ou=developers,dc=wikimedia,dc=org",
]

Don't forget the preceeding c. for setting configuration parameters! JupyterHub uses traitlets for configuration, and the c represents the config object.

The {username} is expanded into the username the user provides.

lookup_dn = True
c.LDAPAuthenticator.lookup_dn = True

If bind_dn_template isn't explicitly configured, i.e. the empty list, the dynamically acquired value for DN from the username lookup will be used instead. If bind_dn_template is configured it will be used just like in the lookup_dn = False case.

The {username} is expanded to the full path to the LDAP object returned by the LDAP lookup. For example, on an Active Directory system {username} might expand to something like CN=First M. Last,OU=An Example Organizational Unit,DC=EXAMPLE,DC=COM.

Also, when using lookup_dn = True the options user_search_base, user_attribute, lookup_dn_user_dn_attribute and lookup_dn_search_filter are required, although their defaults might be sufficient for your use case.

Optional configuration

LDAPAuthenticator.allowed_groups

LDAP groups whose members are allowed to log in. This must be set to either empty [] (the default, to disable) or to a list of full DNs that have a member attribute that includes the current user attempting to log in.

As an example, to restrict access only to people in groups researcher or operations,

c.LDAPAuthenticator.allowed_groups = [
    "cn=researcher,ou=groups,dc=wikimedia,dc=org",
    "cn=operations,ou=groups,dc=wikimedia,dc=org",
]

LDAPAuthenticator.valid_username_regex

All usernames will be checked against this before being sent to LDAP. This acts as both an easy way to filter out invalid usernames as well as protection against LDAP injection attacks.

By default it looks for the regex ^[a-z][.a-z0-9_-]*$ which is what most shell username validators do.

LDAPAuthenticator.use_ssl

Boolean to specify whether to use SSL encryption when contacting the LDAP server. If it is left to False (the default) LDAPAuthenticator will try to upgrade connection with StartTLS. Set this to be True to start SSL connection.

LDAPAuthenticator.server_port

Port to use to contact the LDAP server. Defaults to 389 if no SSL is being used, and 636 is SSL is being used.

LDAPAuthenticator.user_search_base

Only used with lookup_dn=True. Defines the search base for looking up users in the directory.

c.LDAPAuthenticator.user_search_base = 'ou=People,dc=example,dc=com'

LDAPAuthenticator.user_attribute

Only used with lookup_dn=True. Defines the attribute that stores a user's username in your directory.

# Active Directory
c.LDAPAuthenticator.user_attribute = 'sAMAccountName'

# OpenLDAP
c.LDAPAuthenticator.user_attribute = 'uid'

LDAPAuthenticator.lookup_dn_search_filter

How to query LDAP for user name lookup, if lookup_dn is set to True. Default value '({login_attr}={login})' should be good enough for most use cases.

LDAPAuthenticator.lookup_dn_search_user, LDAPAuthenticator.lookup_dn_search_password

Technical account for user lookup, if lookup_dn is set to True. If both lookup_dn_search_user and lookup_dn_search_password are None, then anonymous LDAP query will be done.

LDAPAuthenticator.lookup_dn_user_dn_attribute

Attribute containing user's name needed for building DN string, if lookup_dn is set to True. See user_search_base for info on how this attribute is used. For most LDAP servers, this is username. For Active Directory, it is cn.

LDAPAuthenticator.escape_userdn

If set to True, escape special chars in userdn when authenticating in LDAP. On some LDAP servers, when userdn contains chars like '(', ')', '' authentication may fail when those chars are not escaped.

LDAPAuthenticator.auth_state_attributes

An optional list of attributes to be fetched for a user after login. If found these will be returned as auth_state.

LDAPAuthenticator.use_lookup_dn_username

If set to True (the default) the username used to build the DN string is returned as the username when lookup_dn is True.

When authenticating on a Linux machine against an AD server this might return something different from the supplied UNIX username. In this case setting this option to False might be a solution.

Compatibility

This has been tested against an OpenLDAP server, with the client running Python 3.4. Verifications of this code working well with other LDAP setups are welcome, as are bug reports and patches to make it work with other LDAP setups!

Active Directory integration

Please use following options for AD integration. This is useful especially in two cases:

  • LDAP Search requires valid user account in order to query user database
  • DN does not contain login but some other field, like CN (actual login is present in sAMAccountName, and we need to lookup CN)
c.LDAPAuthenticator.lookup_dn = True
c.LDAPAuthenticator.lookup_dn_search_filter = '({login_attr}={login})'
c.LDAPAuthenticator.lookup_dn_search_user = 'ldap_search_user_technical_account'
c.LDAPAuthenticator.lookup_dn_search_password = 'secret'
c.LDAPAuthenticator.user_search_base = 'ou=people,dc=wikimedia,dc=org'
c.LDAPAuthenticator.user_attribute = 'sAMAccountName'
c.LDAPAuthenticator.lookup_dn_user_dn_attribute = 'cn'
c.LDAPAuthenticator.escape_userdn = False
c.LDAPAuthenticator.bind_dn_template = '{username}'

In setup above, first LDAP will be searched (with account ldap_search_user_technical_account) for users that have sAMAccountName=login Then DN will be constructed using found CN value.

Configuration note on local user creation

Currently, local user creation by the LDAPAuthenticator is unsupported as this is insecure since there's no cleanup method for these created users. As a result, users who are disabled in LDAP will have access to this for far longer.

Alternatively, there's good support in Linux for integrating LDAP into the system user setup directly, and users can just use PAM (which is supported in not just JupyterHub, but ssh and a lot of other tools) to log in. You can see http://www.tldp.org/HOWTO/archived/LDAP-Implementation-HOWTO/pamnss.html and lots of other documentation on the web on how to set up LDAP to provide user accounts for your system. Those methods are very widely used, much more secure and more widely documented. We recommend you use them rather than have JupyterHub create local accounts using the LDAPAuthenticator.

Issue #19 provides additional discussion on local user creation.

More Repositories

1

jupyterhub

Multi-user server for Jupyter notebooks
Python
7,778
star
2

binderhub

Run your code in the cloud, with technology so advanced, it feels like magic!
Python
2,557
star
3

repo2docker

Turn repositories into Jupyter-enabled Docker images
Python
1,621
star
4

zero-to-jupyterhub-k8s

Helm Chart & Documentation for deploying JupyterHub on Kubernetes
Python
1,551
star
5

the-littlest-jupyterhub

Simple JupyterHub distribution for 1-100 users on a single server
Python
1,038
star
6

jupyterhub-deploy-docker

Reference deployment of JupyterHub with docker
Python
699
star
7

kubespawner

Kubernetes spawner for JupyterHub
Python
546
star
8

dockerspawner

Spawns JupyterHub single user servers in Docker containers
Python
489
star
9

oauthenticator

OAuth + JupyterHub Authenticator = OAuthenticator
Python
413
star
10

jupyter-server-proxy

Jupyter notebook server extension to proxy web services.
Python
351
star
11

jupyterhub-deploy-teaching

Reference deployment of JupyterHub and nbgrader on a single server
Jinja
247
star
12

configurable-http-proxy

node-http-proxy plus a REST API
JavaScript
243
star
13

nbgitpuller

Jupyter server extension to sync a git repository one-way to a local path
Python
212
star
14

jupyterhub-tutorial

Tutorial materials for deploying JupyterHub
Shell
196
star
15

batchspawner

Custom Spawner for Jupyterhub to start servers in batch scheduled systems
Python
188
star
16

helm-chart

A store of Helm chart tarballs for deploying JupyterHub and BinderHub on a Kubernetes cluster
187
star
17

jupyterlab-hub

Deprecated: JupyterLab extension for running JupyterLab with JupyterHub
TypeScript
181
star
18

mybinder.org-user-guide

Turn a Git repo into a collection of interactive notebooks. This is Binder's user documentation repository.
Python
158
star
19

repo2docker-action

A GitHub action to build data science environment images with repo2docker and push them to registries.
Shell
142
star
20

jupyter-rsession-proxy

Jupyter extensions for running an RStudio rsession proxy
Python
119
star
21

jupyter-remote-desktop-proxy

Run a Linux Desktop on a JupyterHub
Python
113
star
22

jupyterhub-idle-culler

JupyterHub service to cull idle servers and users
Python
101
star
23

systemdspawner

Spawn JupyterHub single-user notebook servers with systemd
Python
92
star
24

jupyterhub-the-hard-way

Understanding JupyterHub by deploying it step by step
81
star
25

mybinder.org-deploy

Deployment config files for mybinder.org
Jupyter Notebook
76
star
26

nativeauthenticator

JupyterHub-native User Authenticator
Python
72
star
27

ltiauthenticator

A JupyterHub authenticator for LTI
Python
68
star
28

team-compass

A repository for team interaction, syncing, and handling meeting notes across the JupyterHub ecosystem.
Jupyter Notebook
62
star
29

wrapspawner

Mechanism for runtime configuration of spawners for JupyterHub
Python
60
star
30

hubshare

A directory sharing service for JupyterHub
Python
57
star
31

chartpress

automate building and publishing images for helm charts
Python
55
star
32

grafana-dashboards

Grafana Dashboards useful for k8s + JupyterHub
Jsonnet
55
star
33

traefik-proxy

JupyterHub proxy implementation with traefik
Jupyter Notebook
54
star
34

sudospawner

Spawn JupyterHub single-user servers with sudo
Python
50
star
35

firstuseauthenticator

JupyterHub Authenticator that lets users set passwords when they first log in
Python
48
star
36

jupyterhub-deploy-hpc

Documented examples of Jupyterhub deployment in HPC settings
Python
36
star
37

jupyterhub-example-kerberos

Example for experimenting with how JupyterHub can be configured to work with Kerberos
Python
33
star
38

outreachy

Tasks, management and documentation for Outreachy Internships in JupyterHub
Python
33
star
39

pebble-helm-chart

To deploy a server to replace Let's Encrypt in externally unreachable CI environment for testing purposes.
Shell
28
star
40

dummyauthenticator

A Dummy JupyterHub Authenticator to make testing easy
Python
28
star
41

gh-scoped-creds

Provide fine-grained push access to GitHub from a JupyterHub
Python
26
star
42

action-k3s-helm

A GitHub action to install K3S, Calico, and Helm.
25
star
43

tmpauthenticator

JupyterHub authenticator that hands out temporary accounts for everyone. For use in tmpnb.org
Python
22
star
44

yarnspawner

Spawn JupyterHub single user notebook servers in Hadoop/YARN containers.
Python
19
star
45

jupyterhub-on-hadoop

Documentation and resources for deploying JupyterHub on Hadoop
Shell
18
star
46

simpervisor

Simple Python3 Supervisor library
Python
12
star
47

kerberosauthenticator

A JupyterHub authenticator using Kerberos
Python
11
star
48

nullauthenticator

Null Authenticator for JupyterHub instances that should have no login mechanism
Python
9
star
49

binder-data

A place to store data for Binder
Jupyter Notebook
9
star
50

docker-image-cleaner

Python script to cleanup unused docker images
Python
9
star
51

action-k8s-await-workloads

A Github Action to await k8s workloads to become Ready
TypeScript
8
star
52

research-facilities

resources for developing, deploying, and using Jupyter at Research Facilities
8
star
53

simplespawner

A simple variant of LocalProcessSpawner for JupyterHub that doesn't require users exist on the system
Python
6
star
54

action-k8s-namespace-report

GitHub Action to report info and logs from the current namespace.
Shell
6
star
55

pytest-jupyterhub

Reusable pytest plugin for testing JupyterHub's components
Python
5
star
56

binder-billing

A repository to explore billing data for mybinder.org
Jupyter Notebook
3
star
57

autodoc-traits

Sphinx extension to autodocument traitlets
Python
3
star
58

action-major-minor-tag-calculator

GitHub action to calculate major and minor semver tags, e.g. for tagging containers
JavaScript
3
star
59

mybinder-tools

Some tools for munging and utilizing kubectl
Jupyter Notebook
2
star
60

jhub-proposals

Repo for collecting conference proposals, proceedings, &c.
2
star
61

design

A collection of design material for JupyterHub and related projects
2
star
62

alabaster-jupyterhub

A slight modification of the Alabaster theme for use with JupyterHub projects
CSS
2
star
63

katacoda-scenarios

https://katacoda.com/ is a playground for learning, and these are our learning scenarios
1
star
64

nbgitpuller-downloader-googledrive

Python
1
star
65

jupyterhub-python-repo-template

A template for generating Python repositories in the `jupyterhub` organization
Python
1
star
66

.github

1
star
67

nbgitpuller-downloader-plugins

jupyterhub/nbgitpuller allows for content provider plugins, this python package provides downloader plugins
Python
1
star