Как стать автором
Обновить

FastAPI + Keycloak: Простая и безопасная авторизация в веб-приложении на примере реального проекта

Время на прочтение34 мин
Количество просмотров9.3K
Всего голосов 11: ↑11 и ↓0+12
Комментарии6

Комментарии 6

Отличная статья про интеграцию с Keycloak. Но для реального проекта не хватает примера работы с refresh token и снятия нагрузки на keycloak сервер - чтобы не долбить его запросами каждый раз.

Согласен с замечанием. В продолжении, если тема пойдет, обязательно расскажу об этом.

Очень интересно как устроена система ролей.

Давно смотрю на Keycloak, но не понимаю как его правильно готовить, если само приложение multi tenant, причем могут быть пользователи с разным уровнем прав и с доступами к разным tenant.

А еще, чтобы одни пользователи (с определенной ролью) могли назначать роли другим пользователям.

Не часто попадаются такие объёмные статьи по keycloak. Очень много полезной информации.

Мне кажется, что хорошо бы явно указать, что вы пользуетесь токенами JWT. Из контекста статьи это не очень понятно, т.к. есть и другие способы. У меня на работе тоже пользовались токенами JWT, но идея перевести web-приложения на Cookies мне кажется более практичной (или более близкой к типу аутентификации типа NTLM/Kerberos в корпоративной среде). JWT скорее всего нужно там, где Cookies не применимы, например, вне контекстов браузеров, в приложениях mobile/desktop. Кстати, использование только cookies для web-приложений позволяет избежать лишних проверок/нагрузок на сервер keycloak - если cookie есть, то пользователь аутентифицирован, а если что, то сессию всегда можно удалить на сервере и кука станет невалидна и пользователь не сможет ничего сделать без повторной аутентификации.

Соответственно пара вопросов в сравнении с аутентификацией NTLM/Kerberos:

1.Хотелось бы узнать ваше мнение по поводу работы по cookies для web-приложений.

2.У вас написано, что "Если токена нет или он просрочен — редиректим на страницу входа". Это хорошо работает, когда у вас в форме на странице один-два параметра, которые не трудно ввести повторно, но если параметров в форме, например, несколько десятков, то как тогда бороться с этими неожиданными перенаправлениями на аутентификацию? (пользователь же вынужен покинуть страницу с исходной формой ввода). Т.е. для одностраничного web-приложения использование JWT создаёт неудобства (это и пользователю создаёт проблему из-за непредсказуемых переходов и разработчику web-приложения - всё время надо контролировать/проверять ответы от сервера + ещё и следить, что вдруг какой-то админ/друг_админа выдал себе бессрочный JWT-токен, то попробуй поймай его с таким токеном).

P.S.
Немного маловато про realm-ы написано. Realm-ы позволяют автоматически аутентифицировать пользователей в других приложениях этого realm, если пользователь аутентифицирован хотя бы в одном приложении конкретного realm. Это очень удобная фича, которая существенно упрощает аутентификацию в web-приложениях в корпоративной среде. Например, если в двух вкладках одного браузера открыты две формы ввода логина и пароля, то при вводе credentials в одной вкладке произойдёт автоматический вход в приложение в другой вкладке (при открытом окне ввода логина и пароля):

Пример аутентификации пользователя в разных приложениях одного realm без прямого перехода в keycloak (в диалоговом окне на странице приложения через iframe. На экране кастомный диалог keycloak [диалоги аутентификации в keycloak можно кастомизировать])
Пример аутентификации пользователя в разных приложениях одного realm без прямого перехода в keycloak (в диалоговом окне на странице приложения через iframe. На экране кастомный диалог keycloak [диалоги аутентификации в keycloak можно кастомизировать])

Не стоит хардкодить URL до эндпоинтов сервера аутентификации. Все эти URL описаны в стандартизированным документе openid_configuration. Если использовать его, то в конфигурации остаётся только ссылка на issuer. Например для Google issuer равен https://accounts.google.com. Значит документ с конфигурацией находится в https://accounts.google.com/.well-known/openid-configuration.
Не нужно ходить в user_info на каждый запрос пользователя, это просто убьет KC на сколько нибудь серьёзной нагрузке. Вы же использовали OpenID Connect, значит access_token - это JWT токен, который можно и нужно валидировать локально на вашем бакенде.

Я может неправильно понимаю, но у меня сложилось впечатление (разглядывая код), что полученные (и сохраненные в куки) от KC токены используются для хождения на тот же KC. А для бэкенда fastapi используется своя сессионная кука. Или я не прав?

Ну и уникальный идентификатор (UUID) пользователя из КС есть и в access и в id токенах. Еще раз ломиться на КС за ним не обязательно. Разве работу jwt продемонстрировать.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий