bluesky_httpserver.authenticators.LDAPAuthenticator

class bluesky_httpserver.authenticators.LDAPAuthenticator(server_address, server_port=None, *, use_ssl=False, use_tls=True, connect_timeout=5, receive_timeout=60, bind_dn_template=None, allowed_groups=None, valid_username_regex='^[a-z][.a-z0-9_-]*$', lookup_dn=False, user_search_base=None, user_attribute=None, lookup_dn_search_filter='({login_attr}={login})', lookup_dn_search_user=None, lookup_dn_search_password=None, lookup_dn_user_dn_attribute=None, escape_userdn=False, search_filter='', attributes=None, auth_state_attributes=None, use_lookup_dn_username=True)[source]

LDAP authenticator. The authenticator code is based on https://github.com/jupyterhub/ldapauthenticator The parameter use_tls was added for convenience of testing.

Parameters:
server_address: str or list(str)

Address(es) of the LDAP server(s) to contact. A string value may represent a single server, a list of strings may represent one or more servers. If a server address includes port, then the value of server_port is ignored, otherwise server_port or the default port is used to access the server.

Could be an IP address or hostname.

server_port: int or None

Port on which to contact the LDAP server. Default port is used if None.

Defaults to 636 if use_ssl is set, 389 otherwise.

use_ssl: boolean

Use SSL to communicate with the LDAP server.

Deprecated in version 3 of LDAP. Your LDAP server must be configured to support this, however.

use_tls: boolean

Enable/disable TLS if use_ssl is False. By default TLS is enabled. It should not be disabled in production systems.

connect_timeout: float

Timeout used for connecting to the LDAP server. Default: 5.

receive_timeout: float

Timeout used for communication with the LDAP server, e.g. this timeout is used to wait for completion of 2FA. For smooth operation it should probably exceed timeout set at LDAP server. Default: 60.

bind_dn_template: list or str

Template from which to construct the full dn when authenticating to LDAP. {username} is replaced with the actual username used to log in.

If your LDAP is set in such a way that the userdn can not be formed from a template, but must be looked up with an attribute (such as uid or sAMAccountName), please see lookup_dn. It might be particularly relevant for ActiveDirectory installs.

Unicode Example:

"uid={username},ou=people,dc=wikimedia,dc=org"

List Example:

[
    "uid={username},ou=people,dc=wikimedia,dc=org",
    "uid={username},ou=Developers,dc=wikimedia,dc=org"
    ]
allowed_groups: list or None

List of LDAP group DNs that users could be members of to be granted access.

If a user is in any one of the listed groups, then that user is granted access. Membership is tested by fetching info about each group and looking for the User’s dn to be a value of one of member or uniqueMember, or if the username being used to log in with is value of the uid.

Set to an empty list or None to allow all users that have an LDAP account to log in, without performing any group membership checks.

valid_username_regex: str

Regex for validating usernames - those that do not match this regex will be rejected.

This is primarily used as a measure against LDAP injection, which has fatal security considerations. The default works for most LDAP installations, but some users might need to modify it to fit their custom installs. If you are modifying it, be sure to understand the implications of allowing additional characters in usernames and what that means for LDAP injection issues. See https://www.owasp.org/index.php/LDAP_injection for an overview of LDAP injection.

lookup_dn: boolean

Form user’s DN by looking up an entry from directory

By default, LDAPAuthenticator finds the user’s DN by using bind_dn_template. However, in some installations, the user’s DN does not contain the username, and hence needs to be looked up. You can set this to True and then use user_search_base and user_attribute to accomplish this.

user_search_base: str

Base for looking up user accounts in the directory, if lookup_dn is set to True.

LDAPAuthenticator will search all objects matching under this base where the user_attribute is set to the current username to form the userdn.

For example, if all users objects existed under the base ou=people,dc=wikimedia,dc=org, and the username users use is set with the attribute uid, you can use the following config:

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.bind_dn_template = '{username}'
user_attribute: str

Attribute containing user’s name, 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 uid. For Active Directory, it is sAMAccountName.

lookup_dn_search_filter: str or None

How to query LDAP for user name lookup, if lookup_dn is set to True.

lookup_dn_search_user: str or None

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.

lookup_dn_search_password: str or None

Technical account for user lookup, if lookup_dn is set to True.

lookup_dn_user_dn_attribute: str or None

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.

escape_userdn: boolean

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.

search_filter: str

LDAP3 Search Filter whose results are allowed access

attributes: list or None

List of attributes to be searched

auth_state_attributes: list or None

List of attributes to be returned in auth_state for a user

use_lookup_dn_username: boolean

If set to true uses the lookup_dn_user_dn_attribute attribute as username instead of the supplied one.

This can be useful in an heterogeneous environment, when supplying a UNIX username to authenticate against AD.

Examples

Using the authenticator class (the code runs in asyncio loop):

from bluesky_httpserver.authenticators import LDAPAuthenticator
authenticator = LDAPAuthenticator(
    "localhost", 1389, bind_dn_template="cn={username},ou=users,dc=example,dc=org", use_tls=False
)
await authenticator.authenticate("user01", "password1")
await authenticator.authenticate("user02", "password2")

Simple example of a config file (e.g. config_ldap.yml):

uvicorn:
    host: localhost
    port: 60610
authentication:
    providers:
        - provider: ldap_local
        authenticator: bluesky_httpserver.authenticators:LDAPAuthenticator
        args:
            server_address: localhost
            server_port: 1389
            bind_dn_template: "cn={username},ou=users,dc=example,dc=org"
            use_tls: false
            use_ssl: false
    tiled_admins:
        - provider: ldap_local
        id: user02
__init__(server_address, server_port=None, *, use_ssl=False, use_tls=True, connect_timeout=5, receive_timeout=60, bind_dn_template=None, allowed_groups=None, valid_username_regex='^[a-z][.a-z0-9_-]*$', lookup_dn=False, user_search_base=None, user_attribute=None, lookup_dn_search_filter='({login_attr}={login})', lookup_dn_search_user=None, lookup_dn_search_password=None, lookup_dn_user_dn_attribute=None, escape_userdn=False, search_filter='', attributes=None, auth_state_attributes=None, use_lookup_dn_username=True)[source]

Methods

__init__(server_address[, server_port, ...])

authenticate(username, password)

get_connection(userdn, password)

get_user_attributes(conn, userdn)

resolve_username(username_supplied_by_user)

Attributes

mode