Как определить вошедшего пользователя из Keycloak OpenID logout_token при выходе из обратного канала?

Сначала позвольте мне описать установку:

У нас есть frontend продукт на базе Angular от другой команды клиентов (не часть кода, который мы можем легко модифицировать), и backend API сервер на базе django.

Внешняя сторона регистрируется на сервере keycloak, и когда она зарегистрирована, внутренняя сторона получает заголовок Auth с маркером предъявителя в каждом запросе. Из этого мы можем идентифицировать вошедшего пользователя следующим образом (используя python-keycloak):

ret = keycloak.userinfo(bearer_token)
username = ret['preferred_username']

Это, очевидно, очень расточительно, поскольку каждый раз требуется дополнительный сетевой запрос к keycloak - поэтому вместо этого мы создаем сессию пользователя django и используем ее для управления сессиями.

Теперь, когда дело доходит до выхода из системы, когда пользователь выходит из фронт-энда, нам нужно аннулировать сессию django.

Я настроил "Back channel logout URL" в настройках keycloak realm для вызова некоторой конечной точки на сервере django. Конечная точка вызывается при выходе из системы и получает значение "logout_token" в аргументах.

Теперь я не уверен, как я должен определить, какой пользователь выходит из системы, основываясь на этом токене. Как это можно сделать?

Заранее спасибо...

Я не уверен на 100% в правильности вашей архитектуры. Тем не менее, что касается вашего конкретного вопроса:

ret = keycloak.userinfo(bearer_token) 
username = ret['preferred_username']

Из книги "Ключ плаща" :

preferred_username Это имя пользователя, прошедшего аутентификацию. Вам следует избегать этого в качестве ключа для пользователя, так как оно может быть изменено и даже ссылаться на другого пользователя в будущем. другого пользователя в будущем. Вместо этого всегда используйте вложенное поле для ключ пользователя.

Из спецификации OpenID connect specification можно прочитать, что:

OPs посылают JWT, похожий на ID Token, RPs, называемый Logout Token, чтобы запросить, чтобы они вышли из системы. ID Токены определены в Разделе 2 [OpenID.Core].

В токене выхода из системы используются следующие утверждения:

iss REQUIRED. Идентификатор эмитента, (...)

sub OPTIONAL. Идентификатор субъекта,(...)

aud REQUIRED. Аудитория(и), (...)

iat REQUIRED. Выдается в момент, (...)

jti REQUIRED. Уникальный идентификатор для токена, (...) (...) sid OPTIONAL. Идентификатор сессии - строковый идентификатор сессии. Представляет собой сеанс пользовательского агента или устройства для вошедшего в систему конечного пользователя на RP. (..)

Токен выхода ДОЛЖЕН содержать либо sub, либо sid Claim, и МОЖЕТ содержать оба. Если sid Claim не присутствует, то предполагается, что все сессии на RP для конечного пользователя, идентифицированного iss и sub Claims, будут выведены из системы.

.

Поэтому вы можете попробовать использовать утверждение 'sub', которое является уникальным идентификатором аутентифицированного пользователя. Вам (вероятно) потребуется создать связку между 'sub' и 'user' в вашем бэкенде. В качестве альтернативы, вы можете использовать ту же логику, но вместо этого применить ее к 'sid'. Там вы сопоставите ID сессии Keycloak с вашей собственной ID сессией.

Однако, мой вопрос таков:

Фронтэнд входит на сервер keycloak, и когда он входит в систему, бэкэнд получает заголовок Auth с токеном предъявителя в каждом запросе. бэкэнд получает заголовок Auth с токеном предъявителя в каждом запросе.

Из этого токена предъявителя (который, как я предполагаю, является токеном доступа) вы не можете просто получить 'preferred_username' (или лучше 'sub' утверждение) оттуда? Это не потребует дополнительного обращения к серверу Keycloak.

Вернуться на верх