Skip to content

Провайдер Keycloak

Описание

Провайдер аутентификации Keycloak использует библиотеку python-keycloak для взаимодействия с сервером Keycloak. В процессе аутентификации KeycloakAuthProvider перенаправляет пользователя на страницу аутентификации Keycloak.

После успешной аутентификации Keycloak перенаправляет пользователя обратно в Data.Rentgen с кодом авторизации. Затем KeycloakAuthProvider обменивает код авторизации на токен доступа и использует его для получения информации о пользователе с сервера Keycloak. Если пользователь не найден в базе данных Data.Rentgen, KeycloakAuthProvider создает его. Наконец, KeycloakAuthProvider возвращает пользователя с токеном доступа.

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

sequenceDiagram
participant "Фронтенд"
participant "Бэкенд"
participant "Keycloak"


"Фронтенд" -> "Бэкенд" : Запрос эндпоинта с аутентификацией (/v1/locations)

"Бэкенд" --x "Фронтенд": 401 URL-адрес перенаправления в поле ответа 'details'

"Фронтенд" -> "Keycloak" : Перенапраление пользователя на страницу авторизации Keycloak

alt Успешный вход
     "Фронтенд" --> "Keycloak" : Вход по логину и паролю
else Неверный логин
     "Keycloak" --x "Фронтенд" : Отображение ошибки (401 Неавторизован)
end

 "Keycloak" -> "Фронтенд" : Функция обратного вызова для Фронтенда /callback, которая выступает в качестве прокси-сервера между Keycloak и Бэкендом.

"Фронтенд" -> "Бэкенд" : Отправка запроса на Бэкенд '/v1/auth/callback'

"Бэкенд" -> "Keycloak" : Проверка исходного состояния и обмен кодами для токенов
"Keycloak" --> "Бэкенд" : Вернуть токены
"Бэкенд" --> "Фронтенд" : Установить токены в браузере пользователя в файлах cookie.

"Фронтенд" --> "Бэкенд" : Запрос к /v1/locations с файлами cookies сессии
"Бэкенд" -> "Бэкенд" : Получить информацию о пользователе из токена и проверить пользователя во внутренней базе данных бэкенда.
"Бэкенд" -> "Бэкенд" : Создать пользователя во внутреннней базе Бэкенда, если не существует
"Бэкенд" --> "Фронтенд" : Вернуть запрошенные данные

alt Успешный кейс
activate "Бэкенд"
"Фронтенд" -> "Бэкенд" : токен доступа
"Бэкенд" --> "Бэкенд" : Проверка токена
"Бэкенд" --> "Бэкенд" : Проверка пользователя во внутреннней базе данных Бэкенда
"Бэкенд" -> "Бэкенд" : Получение данных
"Бэкенд" --> "Фронтенд" : Возвращение данных
deactivate "Бэкенд"

else Срок действия токена истек (Успешный кейс)
activate "Бэкенд"
"Фронтенд" -> "Бэкенд"  : токен доступа, обновление токена
"Бэкенд" --> "Бэкенд" : Проверка токена
"Бэкенд" --> "Бэкенд" : Срок действия токена истек
"Бэкенд" --> "Keycloak" : Попытка обновить токен
"Бэкенд" --> "Бэкенд" : Проверка нового токена
"Бэкенд" --> "Бэкенд" : Проверка пользователя во внутреннней базе данных Бэкенда
"Бэкенд" -> "Бэкенд" : Получение данных
"Бэкенд" --> "Фронтенд" : Возращение данных
deactivate "Бэкенд"

else Создание нового пользователя
activate "Бэкенд"
"Фронтенд" -> "Бэкенд"  : токен доступа
"Бэкенд" --> "Бэкенд" : Проверка токена
"Бэкенд" --> "Бэкенд" : Проверка пользователя во внутреннней базе данных Бэкенда
"Бэкенд" --> "Бэкенд" : Создание нового пользователя
"Бэкенд" -> "Бэкенд" : Получение данных
"Бэкенд" --> "Фронтенд" : Возращение данных
deactivate "Бэкенд"

else Срок действия токена истек и неверный токен обновления
activate "Бэкенд"
"Фронтенд" -> "Бэкенд" : токен доступа, обновление токена
"Бэкенд" --> "Бэкенд" : Проверка токена
"Бэкенд" --> "Бэкенд" : Срок действия токена истек
"Бэкенд" --> "Keycloak" : Попытка обновить токен
"Бэкенд" --x "Фронтенд" : RedirectResponse не может быть обновлен
deactivate "Бэкенд"

else Неверный токен (Bad Token)
activate "Бэкенд"
"Фронтенд" -> "Бэкенд" : токен доступа, обновление токена
"Бэкенд" --> "Бэкенд" : Проверка токена
"Бэкенд" --x "Фронтенд" : 307 ошибка авторизации
deactivate "Бэкенд"

end

Базовая конфигурация

Bases: BaseModel

Settings related to Keycloak interaction."

Examples

.. code-block:: bash

DATA_RENTGEN__AUTH__PROVIDER=data_rentgen.server.providers.auth.keycloak_provider.KeycloakAuthProvider
DATA_RENTGEN__AUTH__KEYCLOAK__SERVER_URL=http://keycloak:8080
DATA_RENTGEN__AUTH__KEYCLOAK__REDIRECT_URI=http://localhost:8000/auth-callback
DATA_RENTGEN__AUTH__KEYCLOAK__REALM_NAME=fastapi_realm
DATA_RENTGEN__AUTH__KEYCLOAK__CLIENT_ID=fastapi_client
DATA_RENTGEN__AUTH__KEYCLOAK__CLIENT_SECRET=generated_by_keycloak
DATA_RENTGEN__AUTH__KEYCLOAK__SCOPE=email
DATA_RENTGEN__AUTH__KEYCLOAK__VERIFY_SSL=False
Source code in data_rentgen/server/settings/auth/keycloak.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class KeycloakAuthProviderSettings(BaseModel):
    """Settings related to Keycloak interaction."

    Examples
    --------

    .. code-block:: bash

        DATA_RENTGEN__AUTH__PROVIDER=data_rentgen.server.providers.auth.keycloak_provider.KeycloakAuthProvider
        DATA_RENTGEN__AUTH__KEYCLOAK__SERVER_URL=http://keycloak:8080
        DATA_RENTGEN__AUTH__KEYCLOAK__REDIRECT_URI=http://localhost:8000/auth-callback
        DATA_RENTGEN__AUTH__KEYCLOAK__REALM_NAME=fastapi_realm
        DATA_RENTGEN__AUTH__KEYCLOAK__CLIENT_ID=fastapi_client
        DATA_RENTGEN__AUTH__KEYCLOAK__CLIENT_SECRET=generated_by_keycloak
        DATA_RENTGEN__AUTH__KEYCLOAK__SCOPE=email
        DATA_RENTGEN__AUTH__KEYCLOAK__VERIFY_SSL=False
    """

    keycloak: KeycloakSettings = Field(
        description="Keycloak settings",
    )

Bases: BaseModel

Source code in data_rentgen/server/settings/auth/keycloak.py
 6
 7
 8
 9
10
11
12
13
class KeycloakSettings(BaseModel):
    server_url: str = Field(..., description="Keycloak server URL")
    client_id: str = Field(..., description="Keycloak client ID")
    realm_name: str = Field(..., description="Keycloak realm name")
    client_secret: SecretStr = Field(..., description="Keycloak client secret")
    redirect_uri: str = Field(..., description="Redirect URI")
    verify_ssl: bool = Field(default=True, description="Verify SSL certificates")
    scope: str = Field("openid", description="Keycloak scope")