Как настроить OpenID для работы с балансировщиком нагрузки? - PullRequest
0 голосов
/ 17 октября 2019

Стек, который я сейчас использую: Keycloak flask flask-oidc nginx в качестве балансировщика нагрузки

У меня есть два запущенных сервиса (instance1, instance2). Проблема, с которой я сталкиваюсь:

  1. Пользователь использует веб-браузер для аутентификации, перейдя на https://mycompany.com/auth/login
  2. instance1, обрабатывает этот запрос и перенаправляет пользователя на Keycloak для аутентификации
  3. Keycloak перенаправляет пользователя обратно в приложение с помощью URL-адреса перенаправления (https://mycompany.com/auth/auth_callback)
  4. На этот раз балансировщик нагрузки направляет запрос на URL-адрес перенаправления на instance2. Здесь instance2 выдает ошибку с ответомиз Keycloak, говорящего "{'error': 'invalid_grant', 'description': 'неверный URI перенаправления'}", что очень сбивает с толку, потому что URI перенаправления является правильным.

    Я не совсем уверен, почему этот наборup не работает. Но после прочтения того, как работает openID, я подозреваю, что это связано с параметром состояния (https://auth0.com/docs/protocols/oauth2/oauth-state). Опять же, я не совсем уверен. Но это должно быть что-то локальное дляinstance1, которого instance2 не имеет.

Как люди решают эту проблему? Возможна ли такая настройка?

1 Ответ

0 голосов
/ 17 октября 2019

Из документации

Обратите внимание, что вы, вероятно, должны предоставить библиотеке место для хранения учетных данных, которые она получила для пользователя. Они должны храниться в месте, где пользователь или злоумышленник не могут получить к ним доступ. Чтобы обеспечить это, передайте объект, который имеет setitem и getitem dict API, реализованные в качестве второго аргумента вызова init (). Без этого библиотека будет работать только в одном потоке и сохранять сессии только до перезапуска сервера.

Это относится к опции credentials_store в экземпляре OpenIDConnect. Для поддержки постоянного входа в систему через несколько экземпляров приложения вам понадобится постоянное общее хранилище данных для этого варианта использования. Вы можете использовать общий ресурс Redis или DynamodB.

Реализация этого credentials_store довольно проста, вы можете попробовать что-то вроде,

class RedisOpenIdCredStore:
    def __init__(self):
        # Handle Redis instance initialisation here
        pass

    def __setitem__(self, key, value):
        # Set item to redis
        pass

    def __getitem__(self, key):
        # Fetch and return item from redis if present
        pass

credential_store = RedisOpenIdCredStore()
oid_connect = OpenIDConnect(app, credential_store=credential_store, ...)
...