LDAP Auth provider

Description

This auth provider checks for user credentials in LDAP, and and then issues an access token.

All requests to backend should be made with passing this access token. If token is expired, then new auth token should be issued.

After successful auth, username is saved to backend database. It is then used for creating audit records for any object change, see changed_by field.

Warning

Until token is valid, no requests will be made to LDAP to check if user exists and not locked. So do not set access token expiration time for too long (e.g. longer than a day).

Strategies

Note

Basic LDAP terminology is explained here: LDAP Overview

There are 2 strategies to check for user in LDAP:

  • Try to call bind request in LDAP with DN (DistinguishedName) and user password. DN is generated using bind_dn_template

  • First try to lookup for user (search request) in LDAP to get user’s DN using some query, and then try to call bind using this DN. See lookup settings

By default, lookup strategy is used, as it can find user in a complex LDAP/ActiveDirectory environment. For example:

  • you can search for user by uid, e.g. (uid={login}) or (sAMAccountName={login})

  • you can search for user by several attributes, e.g. (|(uid={login})(mail={login}@domain.com))

  • you can filter for entries, like (&(uid={login})(objectClass=person)

  • you can filter for users matching a specific group or some other condition, like (&(uid={login})(memberOf=cn=MyPrettyGroup,ou=Groups,dc=mycompany,dc=com))

After user is found in LDAP, its uid_attribute is used for audit records.

Interaction schema

No lookup
https://www.plantuml.com/plantuml/svg/vLV1RXen4BtdAqRqGaHG4ZMzH08bWOfBHL59saCJ8RCUY8MnLxPtYwf-VCVUXTqLcqARGw7TeptFC-yzs-EziOuPbopb2T3dX9C87_gtezl4FO-CJWL70qsbGMgzIEBJ41OJH4GYPif1eoS5AjVOdhXZqG8Lhvdn2HedORpJWT77yJsab-UCKfuxJHWQpMPPv4JA75QpCEbWd4GHMZjB94JCOXZttpeGsjsY0cYru9eOp8M25fLYxJTjU87PnBKhg6le3w43Kw7uXAk9msKigPXcMEYq3jxDkMK9UqpAW6xsXsURj2LW5jjkVtqpDuZggLifXLOeMEvHREyPemKabWmZda8vD8fH0La4SERObAGwUrG-Hh4b4hd0vGKgvRKDUXkonMUWj0DS2Ulga2Ks6pCycG4gD7uLHjKOT8bHPB3dDmckPvQZj0XVZ5PpY0noWWicBVo01vzxAZMb2GIzUCTi-ug48eBRfjyH5D0ORMfobL0LSQykBk51-IEaZVYEl2Hc44xON3l-oyrnp88Uv3bwsQyh6D8fckb4rPd5KQBxFytwb5qDkG4pVUYMUKBUiaInb0d9fl9GdCbvhDQYx-7EJXNUNRo5CPfKHBZ56DUwK5SVl0zDtMjjOqQdhsZgVzQ-AwrYjrQVcHJSTvjz0NlkeTszSe0kHFzERyptV80LE-i-F8PeQ-4g5cJ6tv3fzGtdkCrz1V_y3lzN-PTlmyhfvxZzRh-XMVhB-0a=
With lookup
https://www.plantuml.com/plantuml/svg/xLTBRnen4BxdLupI2saW3pMz854b8LKkLH8rINie5JBh0IpCU6jx2QdwuplsBYmhI4cRI7t11Mdj6N-ltPqzTbvOdutr5l3FAwyHtfsTN9raVdXbpKH9j52xKtu8sfXHbkx4ZIaNgKIbWZnijxL2yjlB2wSY6I795IlXYEsjUBtLWc8VH2ny8L-ObqFZZIbAO7SNcj1J96ivdBtCeIKnndg1RoyLpjqPAtEWP3o2LOEX1zEVDMd2POe4YI72n2j3qA7K60rzOplaKDXa25yoj0fTXsec3Nk4heF5n8p7Z0cv_GpzrUNr3KmEzmLBjkyDGvvJ4Dnz8XX1HIEXFLndIOBEzJCDYN0OhqVInKRcl210PAtDG17imenWMLCALQbgHWxtqCh_knx7gMOqjTXfPrLzANGJsa9hoCMenGPrw37KhgGw2E-jwcKUNUlbGgEyjD7uz69W4Ubp5Srxz9ab28x1sGK8TZnJiZlljH9GnVW8ARf_Tb67gjDh0JGQtA7K_H7ojOUOZ7AyhBmY7wB608guIk55KAJUeLaAMUiA9UXRCuut56V7fORSGomNZxKOCfEVsmyH1fmgvrTLBX2T9oVmF4T26xe4bMqkl8ZKkp6YUJvHEuIFrj004ekIovNG3hx1RJYxfmqV4xa71fkCFcT6fm41QxuSqLEk1RJMs1M7JSkgYjz71uTmI-4HPApwYdB1t-YbSeMTyeTHtdZyFp-77WxN4LpmKwXlCbgLB8aQ_IPPcsGzMx9YFqvMHc8Yb1Oz_SS4g20oVLACrWhp-k0LNAETg0INHC2PL3nydh-DisTmngM2ZIzdpr-RCYj3mdhvFWYjP9Wp7blmoCIjdvBEqSVTFpCL5VTdB2l3TXDdTauRJbF5PlmEcPx-Nl-xpNq2_-Bjyw_oNtn0Lkv-YSkVbyUyoX_ptm4=

Basic configuration

pydantic model horizon.backend.settings.auth.ldap.LDAPAuthProviderSettings

Settings for LDAPAuthProvider.

Examples

HORIZON__AUTH__PROVIDER=horizon.backend.providers.auth.ldap.LDAPAuthProvider
HORIZON__AUTH__ACCESS_KEY__SECRET_KEY=secret
HORIZON__AUTH__LDAP__URL=ldap://ldap.domain.com:389
HORIZON__AUTH__LDAP__LOOKUP__ENABLED=True
HORIZON__AUTH__LDAP__LOOKUP__POOL__ENABLED=True
HORIZON__AUTH__LDAP__LOOKUP__CREDENTIALS__USER=uid=techuser,ou=users,dc=example,dc=com
HORIZON__AUTH__LDAP__LOOKUP__CREDENTIALS__PASSWORD=somepassword
Fields:
field access_token: JWTSettings [Required]

Access-token related settings

field ldap: LDAPSettings [Required]

LDAP related settings

pydantic model horizon.backend.settings.auth.ldap.LDAPSettings

Settings related to LDAP interaction.

Examples

HORIZON__AUTH__LDAP__URL=ldap://ldap.domain.com:389
HORIZON__AUTH__LDAP__UID_ATTRIBUTE=sAMAccountName
Fields:
field url: Annotated[AnyUrl, UrlConstraints(max_length=None, allowed_schemes=['ldap', 'ldaps'], host_required=True, default_host=None, default_port=None, default_path=None, preserve_empty_path=None)] [Required]

LDAP URL to connect to

Constraints:
  • allowed_schemes = [‘ldap’, ‘ldaps’]

  • host_required = True

field timeout_seconds: int | None = 10

LDAP request timeout, in seconds. None means no timeout

field auth_mechanism: Literal['SIMPLE', 'DIGEST-MD5'] = 'SIMPLE'

LDAP auth mechanism, used for bind request

field base_dn: str [Required]

Organization DN, e.g. ou=users,dc=example,dc=com

field uid_attribute: str = 'uid'

Attribute containing username.

Usually uid (LDAP) or sAMAccountName (ActiveDirectory).

field bind_dn_template: str = '{uid_attribute}={login},{base_dn}'

Template for building DN string, used for checking credentials in LDAP. You can pass any DN value supported by LDAP.

Supported substitution values:
field lookup: LDAPLookupSettings [Optional]

LDAP search options

pydantic model horizon.backend.settings.auth.jwt.JWTSettings

Settings related to JWT tokens.

Examples

HORIZON__AUTH__ACCESS_KEY__SECRET_KEY=somesecret
HORIZON__AUTH__ACCESS_KEY__EXPIRE_SECONDS=3600  # 1 hour
Fields:
field secret_key: SecretStr [Required]

Secret key for signing JWT tokens.

Can be any string. It is recommended to generate random value for every application instance.

field security_algorithm: str = 'HS256'

Algorithm used for signing JWT tokens.

See authlib documentation.

field expire_seconds: int = 36000

Token expiration time, in seconds

pydantic model horizon.backend.settings.auth.ldap.LDAPConnectionPoolSettings

Settings related to LDAP connection pool.

Examples

HORIZON__AUTH__LDAP__LOOKUP__POOL__ENABLED=True
HORIZON__AUTH__LDAP__LOOKUP__POOL__MAX=10
HORIZON__AUTH__LDAP__LOOKUP__POOL__CHECK_ON_STARTUP=True
Fields:
field enabled: bool = True

Set to True to enable connection pool

field initial: int = 1

Initial size of connection pool

field max: int = 10

Maximum size of connection pool