Skip to content

Кешированный LDAP провайдер аутентификации

Описание

То же, что и LDAP провайдер аутентификации, но если запрос LDAP для проверки учетных данных пользователя был успешным, учетные данные сохраняются в локальном кеше (таблица во внутренней базе данных, в форме логин + хеш(пароль) + метка времени обновления).

Следующие запросы аутентификации для того же логина выполняются против этого кеша в первую очередь. Запросы LDAP отправляются только если срок действия кеша истек.

Это позволяет:

  • Обойти ошибки с доступностью LDAP, например, сетевые ошибки
  • Уменьшить количество запросов к LDAP.

Недостатки:

  • Если пользователь изменил пароль, а срок действия кеша еще не истек, пользователь все еще может войти в систему со старыми учетными данными.
  • То же самое, если пользователь был заблокирован в LDAP.

Схема взаимодействия

sequenceDiagram
participant "Клиент"
participant "Бэкенд"
participant "LDAP"
activate "Клиент"
alt Первая аутентификация | Пустой кеш | Срок действия кеша истек
"Клиент" ->> "Бэкенд"  : логин + пароль
"Бэкенд" ->> "Бэкенд" : Поиск кеша учетных данных по логину
"Бэкенд" ->> "Бэкенд" : Записи не найдены или срок действия истек, используется LDAP
"Бэкенд" ->> "Бэкенд" : DN = bind_dn_template(login)
"Бэкенд" ->> "LDAP"  : Вызов bind(DN, password)
"Бэкенд" ->> "Бэкенд" : Проверка пользователя во внутренней базе данных бэкенда,\nusername = login
"Бэкенд" ->> "Бэкенд" : Создание пользователя, если не существует
"Бэкенд" ->> "Бэкенд" : Сохранение учетных данных в кеш
else
"Клиент" ->> "Бэкенд"  : логин + пароль
"Бэкенд" ->> "Бэкенд" : Поиск кеша учетных данных по логину
"Бэкенд" ->> "Бэкенд" : Найдены учетные данные, проверка на истечение срока действия
"Бэкенд" ->> "Бэкенд" : Срок действия не истек, проверка соответствия пароля хешу
"Бэкенд" ->> "Бэкенд" : Пароль совпадает, LDAP не вызывается
"Бэкенд" ->> "Бэкенд" : Проверка пользователя во внутренней базе данных бэкенда
"Бэкенд" ->> "Бэкенд" : Создание пользователя, если не существует
else
"Клиент" ->> "Бэкенд"  : логин + пароль
"Бэкенд" ->> "Бэкенд" : Поиск кеша учетных данных по логину
"Бэкенд" ->> "Бэкенд" : Найдены учетные данные, проверка на истечение срока действия
"Бэкенд" ->> "Бэкенд" : Срок действия не истек, проверка соответствия пароля хешу
"Бэкенд" ->> "Бэкенд" : Пароль не совпадает с локальным кешем
else
"Клиент" ->> "Бэкенд"  : логин + пароль
"Бэкенд" ->> "Бэкенд" : Поиск кеша учетных данных по логину
"Бэкенд" ->> "Бэкенд" : Записи не найдены или срок действия истек, используется LDAP
"Бэкенд" ->> "Бэкенд" : DN = bind_dn_template(login)
else
Note right of "Клиент" : Другие случаи такие же, как для LDAPAuthProvider,\nнапример, поиск, заблокированные/удаленные пользователи
end
alt Успешный случай
"Клиент" ->> "Бэкенд"  : access_token
"Бэкенд" ->> "Бэкенд" : Проверка токена
"Бэкенд" ->> "Бэкенд" : Проверка пользователя во внутренней базе данных бэкенда
"Бэкенд" ->> "Бэкенд" : Получение данных
else
"Клиент" ->> "Бэкенд"  : access_token
"Бэкенд" ->> "Бэкенд" : Проверка токена
else
"Клиент" ->> "Бэкенд"  : access_token
"Бэкенд" ->> "Бэкенд" : Проверка токена
"Бэкенд" ->> "Бэкенд" : Проверка пользователя во внутренней базе данных бэкенда
else
"Клиент" ->> "Бэкенд"  : access_token
"Бэкенд" ->> "Бэкенд" : Проверка токена
"Бэкенд" ->> "Бэкенд" : Проверка пользователя во внутренней базе данных бэкенда
end
deactivate "Клиент"

Конфигурация

Другие настройки точно такие же, как для LDAPAuthProvider

Bases: LDAPAuthProviderSettings

Settings for CachedLDAPAuthProvider.

Examples

.. code-block:: bash

HORIZON__AUTH__PROVIDER=horizon.backend.providers.auth.cached_ldap.CachedLDAPAuthProvider
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
HORIZON__AUTH__CACHE__EXPIRE_SECONDS=3600  # 1 hour
Source code in horizon/backend/settings/auth/cached_ldap.py
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
class CachedLDAPAuthProviderSettings(LDAPAuthProviderSettings):
    """Settings for CachedLDAPAuthProvider.

    Examples
    --------

    .. code-block:: bash

        HORIZON__AUTH__PROVIDER=horizon.backend.providers.auth.cached_ldap.CachedLDAPAuthProvider
        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
        HORIZON__AUTH__CACHE__EXPIRE_SECONDS=3600  # 1 hour
    """

    cache: LDAPCacheSettings = Field(default_factory=LDAPCacheSettings, description="Cache related settings")

Bases: BaseModel

Settings related to LDAP credentials cache.

Examples

.. code-block:: bash

HORIZON__AUTH__CACHE__EXPIRE_SECONDS=3600  # 1 hour
Source code in horizon/backend/settings/auth/cached_ldap.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
class LDAPCacheSettings(BaseModel):
    """Settings related to LDAP credentials cache.

    Examples
    --------

    .. code-block:: bash

        HORIZON__AUTH__CACHE__EXPIRE_SECONDS=3600  # 1 hour
    """

    expire_seconds: int = Field(
        default=60 * 60,
        description=textwrap.dedent(
            """
            Credentials cache expiration time, in seconds.

            .. warning::

                Please do not set too large value here, as it may lead to security issues.
            """,
        ),
    )
    password_hash: LDAPCachePasswordHashSettings = Field(
        default_factory=LDAPCachePasswordHashSettings,
        description="Password hashing options",
    )

Bases: BaseModel

Settings related to LDAP credentials cache password hashing.

Examples

.. code-block:: bash

HORIZON__AUTH__CACHE__PASSWORD_HASH__ALGORITHM=argon2
HORIZON__AUTH__CACHE__PASSWORD_HASH__OPTIONS={"time_cost": 2, "memory_cost": 1024, "parallelism": 1}
Source code in horizon/backend/settings/auth/cached_ldap.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
class LDAPCachePasswordHashSettings(BaseModel):
    """Settings related to LDAP credentials cache password hashing.

    Examples
    --------

    .. code-block:: bash

        HORIZON__AUTH__CACHE__PASSWORD_HASH__ALGORITHM=argon2
        HORIZON__AUTH__CACHE__PASSWORD_HASH__OPTIONS={"time_cost": 2, "memory_cost": 1024, "parallelism": 1}
    """

    algorithm: str = Field(
        default="argon2",
        description=textwrap.dedent(
            """
            Hashing algorithm used to hash user credentials.

            See `passlib documentation <https://passlib.readthedocs.io/en/stable/lib/passlib.hash.html#active-hashes>`_
            for more details.
            """,
        ),
    )
    options: Dict[str, Any] = Field(
        default={},
        description="Options passed to hashing algorithm",
    )