Skip to main content

LDAP Authenticator for JupyterHub

Project description

jupyterhub-ldap-authenticator

LDAP Authenticator plugin for JupyterHub. This project was written with Enterprise LDAP integration in mind and includes the following features:

  • Supports multiple LDAP servers and allows for configuration of server_pool_strategy
  • Uses single read-only LDAP connection per authentication request
  • Verifies authenticating user exists in LDAP and is a member of allowed_groups before testing authentication
  • Supports using nested groups in allowed_groups list
  • Supports domain user home directory creation at login

This project was inspired by the ldapauthenticator project

Installation

Install with pip:

pip install jupyterhub-ldap-authenticator

Configuration

To enable LDAPAuthenticator, add the following line to the Jupyterhub config file and extend configuration with the parameters listed below.

c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
LDAPAuthenticator.server_hosts
List of Names, IPs, or the complete URLs in the scheme://hostname:hostport format of the server (required).
# example- list of complete urls
c.LDAPAuthenticator.server_hosts = ['ldaps://ldap1.example.com:636', 'ldaps://ldap2.example.com:636']

# example - list of names
c.LDAPAuthenticator.server_hosts = ['ldap1.example.com', 'ldap2.example.com']

# example - list of ips
c.LDAPAuthenticator.server_hosts = ['10.0.0.1', '10.0.0.2']
LDAPAuthenticator.server_port
The port where the LDAP server is listening. Typically 389, for a cleartext connection, and 636 for a secured connection (defaults to None).
# example
c.LDAPAuthenticator.server_port = 636
LDAPAuthenticator.server_use_ssl
Boolean specifying if the connection is on a secure port (defaults to False).
# example
c.LDAPAuthenticator.server_use_ssl = True
LDAPAuthenticator.server_connect_timeout
Timeout in seconds permitted when establishing an ldap connection before raising an exception (defaults to None).
# example
c.LDAPAuthenticator.server_connect_timeout = 10
LDAPAuthenticator.server_receive_timeout
Timeout in seconds permitted for responses from established ldap connections before raising an exception (defaults to None).
# example
c.LDAPAuthenticator.server_receive_timeout = 10
LDAPAuthenticator.server_pool_strategy
Available Pool HA strategies (defaults to 'FIRST').
  • FIRST: Gets the first server in the pool, if 'server_pool_active' is set to True gets the first available server.
  • ROUND_ROBIN: Each time the connection is open the subsequent server in the pool is used. If 'server_pool_active' is set to True unavailable servers will be discarded.
  • RANDOM: each time the connection is open a random server is chosen in the pool. If 'server_pool_active' is set to True unavailable servers will be discarded.
# example
c.LDAPAuthenticator.server_pool_strategy = 'FIRST'
LDAPAuthenticator.server_pool_active
If True the ServerPool strategy will check for server availability. Set to Integer for maximum number of cycles to try before giving up (defaults to True).
# example - boolean
c.LDAPAuthenticator.server_pool_active = True

# example - maximum number of tries
c.LDAPAuthenticator.server_pool_active = 3
LDAPAuthenticator.server_pool_exhaust
If True, any inactive servers will be removed from the pool. If set to an Integer, this will be the number of seconds an unreachable server is considered offline. When this timeout expires the server is reinserted in the pool and checked again for availability (defaults to False).
# example - boolean
c.LDAPAuthenticator.server_pool_exhaust = True

# example - offline timeout
c.LDAPAuthenticator.server_pool_exhaust = 600
LDAPAuthenticator.bind_user_dn
The account of the user to log in for simple bind (defaults to None).
# example - freeipa
c.LDAPAuthenticator.bind_user_dn = 'uid=imauser,cn=users,cn=accounts,dc=example,dc=com'

# example - Active Directory
c.LDAPAuthenticator.bind_user_dn = 'CN=imauser,CN=Users,DC=example,DC=com'
LDAPAuthenticator.bind_user_password
The password of the user for simple bind (defaults to None).
# example
c.LDAPAuthenticator.bind_user_password = 'password'
LDAPAuthenticator.user_search_base
The location in the Directory Information Tree where the user search will start.
# example - freeipa
c.LDAPAuthenticator.user_search_base = 'cn=users,cn=accounts,dc=example,dc=com'

# example - active directory
c.LDAPAuthenticator.user_search_base = 'CN=Users,DC=example,DC=com'
LDAPAuthenticator.user_search_filter
LDAP search filter to validate that the authenticating user exists within the organization. Search filters containing '{username}' will have that value substituted with the username of the authenticating user.
# example - freeipa
c.LDAPAuthenticator.user_search_filter = '(&(objectClass=person)(uid={username}))'

# example - active directory
c.LDAPAuthenticator.user_search_filter = '(&(objectCategory=person)(objectClass=user)(sAMAccountName={username}))'
LDAPAuthenticator.user_membership_attribute
LDAP Attribute used to associate user group membership (defaults to 'memberOf').
# example
c.LDAPAuthenticator.user_membership_attribute = 'memberOf'
LDAPAuthenticator.group_search_base
The location in the Directory Information Tree where the group search will start. Search string containing '{group}' will be substituted with entries taken from allowed_groups
# example - freeipa
c.LDAPAuthenticator.group_search_base = 'cn=groups,cn=accounts,dc=example,dc=com'

# example - active directory
c.LDAPAuthenticator.group_search_base = 'CN=Groups,DC=example,DC=com'
LDAPAuthenticator.group_search_filter
LDAP search filter to return members of groups defined in the allowed_groups parameter. Search filters containing '{group}' will have that value substituted with the group dns provided in the allowed_groups parameter.
# example - freeipa
c.LDAPAuthenticator.group_search_filter = '(&(objectClass=ipausergroup)(memberOf={group}))'

# example - active directory
c.LDAPAuthenticator.group_search_filter = '(&(objectClass=group)(memberOf={group}))'
LDAPAuthenticator.allowed_groups
List of LDAP group DNs that users must be a member of in order to be granted login. If left undefined or set to None, allowed_groups will be short-circuited and all users will be allowed (defaults to None).
# example
c.LDAPAuthenticator.allowed_groups = ['cn=jupyterhub-users,cn=groups,cn=accounts,dc=example,dc=com']
LDAPAuthenticator.allow_nested_groups
Boolean allowing for recursive search of members within nested groups of allowed_groups (defaults to False).
# example
c.LDAPAuthenticator.allow_nested_groups = True
LDAPAuthenticator.username_pattern
Regular expression pattern that all valid usernames must match. If a username does not match the pattern specified here, authentication will not be attempted. If not set, allow any username (defaults to None).
# example - freeipa
c.LDAPAuthenticator.username_pattern = '[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?'

# example - active directory
c.LDAPAuthenticator.username_pattern = '[a-zA-Z0-9_.][a-zA-Z0-9_.-]{8,20}[a-zA-Z0-9_.$-]?'
LDAPAuthenticator.create_user_home_dir
Boolean allowing for user home directory to be created at login
# example
c.LDAPAuthenticator.create_user_home_dir = True
LDAPAuthenticator.create_user_home_dir_cmd
Command used when creating a userhome directory as a list of strings. The username will be appended as the final argument. Defaults to `mkhomedir_helper` on linux systems.
# example
c.LDAPAuthenticator.create_user_home_dir_cmd = ['mkhomedir_helper']

Examples

FreeIPA Integration
# freeipa example
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.server_hosts = ['ldaps://ldap1.example.com:636', 'ldaps://ldap2.example.com:636']
c.LDAPAuthenticator.bind_user_dn = 'uid=imauser,cn=users,cn=accounts,dc=example,dc=com'
c.LDAPAuthenticator.bind_user_password = 'imapassword'
c.LDAPAuthenticator.user_search_base = 'cn=users,cn=accounts,dc=example,dc=com'
c.LDAPAuthenticator.user_search_filter = '(&(objectClass=person)(uid={username}))'
c.LDAPAuthenticator.user_membership_attribute = 'memberOf'
c.LDAPAuthenticator.group_search_base = 'cn=groups,cn=accounts,dc=example,dc=com'
c.LDAPAuthenticator.group_search_filter = '(&(objectClass=ipausergroup)(memberOf={group}))'
c.LDAPAuthenticator.allowed_groups = ['cn=jupyterhub-users,cn=groups,cn=accounts,dc=example,dc=com']
c.LDAPAuthenticator.allow_nested_groups = True
c.LDAPAuthenticator.username_pattern = '[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?'
c.LDAPAuthenticator.create_user_home_dir = True
c.LDAPAuthenticator.create_user_home_dir_cmd = ['mkhomedir_helper']
Active Directory Integration
# active directory example
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.server_hosts = ['ldaps://ldap1.example.com:636', 'ldaps://ldap2.example.com:636']
c.LDAPAuthenticator.bind_user_dn = 'CN=imauser,CN=Users,DC=example,DC=com'
c.LDAPAuthenticator.bind_user_password = 'imapassword'
c.LDAPAuthenticator.user_search_base = 'CN=Users,DC=example,DC=com'
c.LDAPAuthenticator.user_search_filter = '(&(objectCategory=person)(objectClass=user)(sAMAccountName={username}))
c.LDAPAuthenticator.user_membership_attribute = 'memberOf'
c.LDAPAuthenticator.group_search_base = 'CN=Groups,DC=example,DC=com'
c.LDAPAuthenticator.group_search_filter = '(&(objectClass=group)(memberOf={group}))'
c.LDAPAuthenticator.allowed_groups = ['CN=jupyterhub-users,CN=Groups,DC=example,DC=com']
c.LDAPAuthenticator.allow_nested_groups = True
c.LDAPAuthenticator.username_pattern = '[a-zA-Z0-9_.][a-zA-Z0-9_.-]{8,20}[a-zA-Z0-9_.$-]?'
c.LDAPAuthenticator.create_user_home_dir = True
c.LDAPAuthenticator.create_user_home_dir_cmd = ['mkhomedir_helper']
OpenLDAP Integration

Because OpenLDAP does not natively support the memberOf attribute in their user objects, the allowed_groups scoping has been short-circuited in the following example:

# openldap example
c.JupyterHub.authenticator_class = 'ldapauthenticator.LDAPAuthenticator'
c.LDAPAuthenticator.server_hosts = ['ldaps://ldap1.example.com:636', 'ldaps://ldap2.example.com:636']
c.LDAPAuthenticator.bind_user_dn = 'uid=imauser,ou=People,dc=example,dc=com'
c.LDAPAuthenticator.bind_user_password = 'imapassword'
c.LDAPAuthenticator.user_search_base = 'ou=People,dc=example,dc=com'
c.LDAPAuthenticator.user_search_filter = '(&(objectClass=posixAccount)(uid={username}))'
c.LDAPAuthenticator.username_pattern = '[a-zA-Z0-9_.][a-zA-Z0-9_.-]{0,252}[a-zA-Z0-9_.$-]?'
c.LDAPAuthenticator.create_user_home_dir = True
c.LDAPAuthenticator.create_user_home_dir_cmd = ['mkhomedir_helper']

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

jupyterhub-ldap-authenticator-0.4.1.tar.gz (12.0 kB view details)

Uploaded Source

Built Distribution

File details

Details for the file jupyterhub-ldap-authenticator-0.4.1.tar.gz.

File metadata

  • Download URL: jupyterhub-ldap-authenticator-0.4.1.tar.gz
  • Upload date:
  • Size: 12.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.4.0.post20200518 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for jupyterhub-ldap-authenticator-0.4.1.tar.gz
Algorithm Hash digest
SHA256 85f981a359693ff9c7123d0b5c4614f53bcea9363fb096b7e3123b0a67757409
MD5 5b83a4268a73984dad21742af9680055
BLAKE2b-256 3db2ae1bf57bd750ab93eaf5ca29976a4e390146b7cc50e71c759dc134818c03

See more details on using hashes here.

File details

Details for the file jupyterhub_ldap_authenticator-0.4.1-py3-none-any.whl.

File metadata

  • Download URL: jupyterhub_ldap_authenticator-0.4.1-py3-none-any.whl
  • Upload date:
  • Size: 11.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.5.0.1 requests/2.23.0 setuptools/46.4.0.post20200518 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.3

File hashes

Hashes for jupyterhub_ldap_authenticator-0.4.1-py3-none-any.whl
Algorithm Hash digest
SHA256 dde410cf440c03d9f04cc63b2a0680512a970ca907b089759eb874fb9e3a60db
MD5 49739a34aeb23192a1aad4bf311572cc
BLAKE2b-256 271a7ae0ee68ab5c845f34cd7214ca90748dff09a9b7cca92f4b5b1a287e33bc

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page