Выход из системы на Spring Authorization Server не прерывает сеанс пользователя в Keycloak

Я пытаюсь реализовать механизм logout, инициированный конечным пользователем.

У меня задействовано 4 основных субъекта.

  • Клиент: Angular приложение, зарегистрированное как общедоступный OIDC клиент на Keycloak.
  • Keycloak: ведет себя как брокер идентификации
  • Spring Authorization Server: поставщик удостоверений, зарегистрированный на Keycloak
  • Сервер ресурсов: Spring Boot приложение с защищенной REST конечной точкой.

Когда конечный пользователь инициирует logout, приложение Angular вызывает end_session_endpoint Keycloak. Я настроил URL-адрес logout для своего поставщика удостоверений (Spring Authorization Server) в Keycloak как http://localhost:9000/logout, который является конечной точкой выхода Spring Security по умолчанию.

К вашему сведению: я не включил BackChannel или FrontChannel выход из системы.

На вкладке Network в Developer Console последовательность вызовов происходит, как показано ниже:

При проверке журналов DEBUG в Spring Authorization Server я вижу, что logout происходит для этого конкретного конечного пользователя, включая аннулирование JSESSIONID, однако сеанс не завершается в Keycloak, что заставляет пользователя оставаться в системе и получать доступ к защищенному REST конечная точка.

Ожидается ли, что Spring Authorization Server вернет Keycloak определенный ответ, чтобы сообщить, что процесс logout завершен в конце и что Keycloak может завершить сеанс сейчас?

Это моя логика для logout в Spring Authorization Server.

@Bean
@Order(Ordered.LOWEST_PRECEDENCE)
public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {

    http.csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(
                        authorize -> authorize.mvcMatchers("/hello/**").permitAll().anyRequest().authenticated())
                .formLogin(form -> form.loginPage("/login").permitAll())
                .addFilterAfter(cookieFilter, ChannelProcessingFilter.class)
                .logout().logoutSuccessUrl("http://localhost:4200");
        
    return http.build();
}

Я совершенно не понимаю, чего мне не хватает, чтобы Keycloak завершил сеанс в конце. Любые выводы будут высоко оценены.

Спасибо!

Обновление: параметр post_logout_redirect_uri отправляется в запросе logout на Spring Authorization Server. Я не вижу перенаправления с этим URI, что может быть причиной того, что сеанс Keycloak не завершается.

post_logout_redirect_uri=http://127.0.0.1:8080/auth/realms/SpringBootKeycloak/broker/oidc/endpoint/logout_response
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
240
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Получил это, чтобы работать наконец!

logoutSuccessUrl("http://localhost:4200") неверно.

Как я упоминал в разделе «Обновление» моего вопроса, Keycloak отправляет параметр post_logout_redirect_uri (проверил конечную точку logout в вызовах Network в Chrome Developer Console), logoutSuccessUrl или redirectUri следует установить на

http://127.0.0.1:8080/auth/realms/SpringBootKeycloak/broker/oidc/endpoint/logout_response

Также обратите внимание, что приведенный выше URL-адрес принимает state в качестве параметра запроса. Сначала он поставил мне 400 Bad Request, так как я не отправил state.

Поскольку мне нужно было перехватывать параметр state, когда logout инициируется в Spring Authorization Server, я добавил собственный обработчик выхода из системы, чтобы выполнить эту работу.

@Component
public class IdpLogoutHandler implements LogoutHandler {

    private static final String STATE = "state";

    @Override
    public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
        String state = request.getParameter(STATE);
        try {
            response.sendRedirect(
                    "http://127.0.0.1:8080/auth/realms/SpringBootKeycloak/broker/oidc/endpoint/logout_response?state = "
                            + state);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Обновлено WebSecurityConfig:

http.csrf(csrf -> csrf.disable())
                .authorizeHttpRequests(
                        authorize -> authorize.mvcMatchers("/hello/**").permitAll().anyRequest().authenticated())
                .formLogin(form -> form.loginPage("/login").permitAll())
                .addFilterAfter(cookieFilter, ChannelProcessingFilter.class).logout()
                .addLogoutHandler(customLogoutHandler);

Другие вопросы по теме