OIDC с Keycloak и Django - Отсутствующие государства
Я пытаюсь настроить OIDC с Keycloak в качестве IdP и Django (используя Django Rest Framework и mozilla-django-oidc) в качестве клиентского сервера. Я установил keycloak и создал примерное приложение Django, которое успешно перенаправляет на keycloak, где я могу успешно аутентифицироваться (на keycloak), но когда я перенаправляюсь обратно на django, мне не хватает информации, в частности oidc_states
.
Перенаправление на django вызывает эту запись в журнале:
[12/Oct/2021 08:28:06] "GET /api/oidc/callback/?state=QGsO26esqdtHZcsfRfYoXvUy0QWcGdZv&session_state=493887a4-600e-4dd2-aaaf-4134ea671c9a&code=dfe1573e-cf8e-4829-8874-a3500ba63712.493887a4-600e-4dd2-aaaf-4134ea671c9a.c1dfdb46-140c-4ccd-8308-6db3b468346a HTTP/1.1" 302 0
Содержит три ключа: state
, session_state
и code
.
Представление обратного вызова по умолчанию, предоставляемое mozilla-django-oidc, содержит следующее:
def get(self, request):
"""Callback handler for OIDC authorization code flow"""
if request.GET.get('error'):
if request.user.is_authenticated:
auth.logout(request)
assert not request.user.is_authenticated
elif 'code' in request.GET and 'state' in request.GET:
if 'oidc_states' not in request.session:
return self.login_failure()
# ...
Поскольку keycloak не делает перенаправление с добавлением oidc_states
, это немедленно приводит к неудаче, и я не смог понять, почему. Я предполагаю, что проблема в конфигурации моего клиента keycloak?
Всем заблудшим путешественникам я желаю удачи. В конце концов, я решил свою проблему, изменив настройки mozilla-django-oidc. В частности, мне не хватало:
AUTHENTICATION_BACKENDS = (
"django.contrib.auth.backends.ModelBackend", # default
"mozilla_django_oidc.auth.OIDCAuthenticationBackend",
)
Это позволило моему приложению аутентифицироваться как с помощью существующего потока, так и используя новый поток OIDC. Вызов authenticate
в представлении обратного вызова OIDC был неудачным, потому что я не указал бэкэнд аутентификации, поэтому он пытался использовать бэкэнд по умолчанию.