Привет! Давай разберем, как работает Backchannel Logout в OpenID Connect (OIDC) и как это можно реализовать с использованием Spring Security для OAuth2.
Backchannel Logout в OpenID Connect — это механизм, при котором сервер авторизации уведомляет сервис клиентов о выходе пользователя (logout). Этот механизм предназначен для того, чтобы клиент мог корректно обработать выход, даже если пользователь не взаимодействует с фронтендом, а все происходит в "тени" (через сервер).
Инициация Logout: Когда пользователь выходит из системы, например, нажимая кнопку "выход" на фронте, сервер авторизации может отправить запрос на клиентский сервер, чтобы сообщить ему о выходе пользователя.
Сообщение о выходе: Сервер авторизации генерирует OIDC Logout Token (logout_token), который будет отправлен на сервер клиента для подтверждения выхода.
Обработка Logout на клиенте: Клиент должен обрабатывать запросы на URL типа /logout/connect/back-channel/{registrationId}, получая logout_token в запросе.
Почему нет LogoutHandler в Spring OAuth2 Authorization Server?
LogoutHandler, о котором вы упоминаете, не является частью Spring Security OAuth2 Authorization Server, потому что Backchannel Logout — это специфическая часть протокола OpenID Connect, который работает на уровне серверов авторизации и клиентов. В Spring Security Authorization Server фокус в основном на обработке авторизации и выдачи токенов, а не на действиях, которые происходят в процессе выхода (logout) в клиентских приложениях.
Кроме того, реализация Backchannel Logout зависит от конфигурации вашего OIDC-поставщика и сервисов клиентов, а также от того, как обрабатываются сессии в вашем приложении. Это делает задачу не универсальной для всех клиентов и серверов.
Пошаговое объяснение реализации
Сервер авторизации инициирует запрос на выход (Backchannel Logout):
Когда на сервере авторизации происходят события выхода (например, через кнопку "выход" на фронте или по таймеру сессии), сервер авторизации генерирует OIDCLogoutToken.
Отправка logout-запроса клиенту:
Сервер авторизации отправляет HTTP POST запрос на URL /logout/connect/back-channel/{registrationId} с параметром logout_token. Это уведомление о том, что пользователь должен выйти из системы на стороне клиента.
POST /logout/connect/back-channel/{registrationId}
Content-Type: application/json
{
"logout_token": "someLogoutTokenValue"
}
Регистрация клиента: В URL {registrationId} вы указываете идентификатор регистрации клиента, который был настроен на сервере авторизации. Это используется для точной идентификации клиента, которому нужно отправить уведомление о выходе.
Настройка клиента (Spring):
На стороне клиента вам нужно настроить Spring Security для обработки Backchannel Logout.
В частности, вам нужно настроить Spring Security с использованием OIDC и обеспечить корректную обработку сообщения о выходе через oidcLogout и настройку backChannel.
Пример конфигурации клиента:
.oidcLogout { oidcLogoutSpec ->
oidcLogoutSpec.backChannel { backChannelSpec ->
// Конфигурация обработки backchannel logout
}
oidcLogoutSpec.oidcSessionRegistry(redisReactiveOidcSessionRepository)
}
Здесь oidcSessionRegistry управляет сессиями пользователя (например, хранит их в Redis), а backChannel отвечает за обработку запросов на выход от сервера авторизации.
Преобразование OidcLogoutToken в logout_token
На сервере авторизации вы получаете OidcLogoutToken. Для того, чтобы отправить его клиенту, вам нужно:
Преобразовать OidcLogoutToken в строку (если требуется, вы можете закодировать его, например, в Base64, чтобы передать через HTTP как параметр logout_token).
Отправить POST-запрос на сервер клиента по URL /logout/connect/back-channel/{registrationId}?logout_token=..., где {registrationId} — это идентификатор клиента, а logout_token — сам токен.
Реализация на стороне клиента:
На стороне клиента вам нужно настроить механизм для получения уведомлений о выходе через Backchannel. Это можно сделать следующим образом:
На клиенте будет обработка URL /logout/connect/back-channel/{registrationId}, который будет обрабатывать POST-запросы, отправленные сервером авторизации.
Когда клиент получает такой запрос, он может выполнить действия по удалению сессии пользователя или очистке других данных (например, удаление access_token).
Пример настройки клиента:
Вот пример, как это может выглядеть в Spring:
// Конфигурация клиента для обработки logout
http.oauth2Login()
.oidcLogout { oidcLogoutSpec ->
oidcLogoutSpec.backChannel { backChannelSpec ->
// Пример конфигурации для backchannel logout
// Вы можете здесь указать дополнительные параметры, например, Redis репозиторий сессий
}
oidcLogoutSpec.oidcSessionRegistry(redisReactiveOidcSessionRepository)
}
Backchannel Logout — это способ уведомления клиентов о выходе пользователя без необходимости взаимодействовать с фронтендом.
Spring Security OAuth2 предоставляет инструменты для настройки Backchannel Logout в клиентской части через oidcLogout и backChannel.
На сервере авторизации вы генерируете OidcLogoutToken и отправляете его клиенту через HTTP POST запрос по URL /logout/connect/back-channel/{registrationId}.
На стороне клиента необходимо настроить обработку этих запросов, чтобы выполнить действия по очистке сессий или другим действиям.