«1. Обзор

В этом коротком руководстве мы подробно рассмотрим, как отключить переадресацию выхода из системы в Spring Security.

Сначала мы начнем с краткой информации о том, как работает процесс выхода из системы в Spring Security. Затем мы проиллюстрируем на практическом примере, как избежать перенаправления пользователей после успешного выхода из системы.

2. Выход из системы в Spring Security

Короче говоря, Spring Security обеспечивает встроенную поддержку механизма выхода из системы с помощью DSL-метода logout(). По сути, Spring Security запускает выход из системы, когда пользователь нажимает URL-адрес выхода по умолчанию, который является /logout.

Стоит отметить, что значение по умолчанию для URL-адреса выхода было /j_spring_security_logout до Spring Security 4.

Spring Security предлагает возможность перенаправить пользователей на определенный URL-адрес после выхода из системы. Однако в некоторых случаях мы хотим избежать такого поведения.

Итак, без лишних слов, давайте посмотрим, как реализовать логику отключения перенаправления выхода из системы в Spring Security.

3. Отключите перенаправление выхода Spring Security

По умолчанию Spring Security перенаправляет пользователей на /login?logout после успешного выхода. Итак, в этом разделе мы сосредоточимся на том, как предотвратить перенаправление пользователя на страницу входа после выхода из системы.

Обратите внимание, что мы можем переопределить URL-адрес перенаправления по умолчанию с помощью DSL-метода logoutSuccessUrl().

Основная цель здесь — показать, как избежать перенаправления, когда URL-адрес /logout вызывается из клиента REST.

Фактически, интерфейс LogoutSuccessHandler предлагает гибкий способ выполнения пользовательской логики при успешном выходе из системы.

Итак, здесь мы будем использовать собственный LogoutSuccessHandler, чтобы возвращать только чистый код состояния 200. Таким образом, он не будет перенаправлять нас ни на одну страницу.

Теперь давайте реализуем необходимую конфигурацию Spring Security, необходимую для отключения перенаправления выхода из системы:

@Configuration
@EnableWebSecurity
public class SpringSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .authorizeRequests(authz -> authz
                .mvcMatchers("/login").permitAll()
                .anyRequest().authenticated()
            )
            .logout(logout -> logout
                .permitAll()
                .logoutSuccessHandler((request, response, authentication) -> {
                    response.setStatus(HttpServletResponse.SC_OK);
                }
            );
    }

}

Важной частью приведенной выше конфигурации является метод logoutSuccessHandler(). Как мы видим, мы используем лямбда-выражение для определения нашего пользовательского обработчика успешного выхода из системы.

Имейте в виду, что мы также можем создать простой класс реализации интерфейса LogoutSuccessHandler и использовать DSL для передачи его в метод logoutSuccessHandler().

4. Тестирование

Теперь, когда мы собрали все части вместе, давайте проверим конечную точку /logout, чтобы убедиться, что все работает так, как ожидалось.

Обратите внимание, что мы будем использовать MockMvc для отправки запроса /logout в нашем тесте.

Во-первых, давайте создадим простой тестовый класс и добавим в него объект MockMvc:

public class LogoutApplicationUnitTest {

    @Autowired
    private MockMvc mockMvc;

    // test case

}

Теперь давайте напишем метод для проверки нашей конечной точки /logout:

@Test
public void whenLogout_thenDisableRedirect() throws Exception {

    this.mockMvc.perform(post("/logout").with(csrf()))
        .andExpect(status().isOk())
        .andExpect(jsonPath("$").doesNotExist())
        .andExpect(unauthenticated())
        .andReturn();
}

Наконец, попробуем сломать вниз наш тестовый код:

    Perform(post(“/logout”) вызывает конечную точку /logout как простой запрос POST with(csrf()) добавляет ожидаемый параметр _csrf к запросу status() возвращает статус код HTTP-ответа jsonPath() позволяет получить доступ и проверить тело HTTP-ответа

5. Заключение

Подводя итог, мы объяснили и проиллюстрировали, как решить проблему отключения перенаправления выхода из системы в Spring Security и весенняя загрузка.

Как обычно, полный исходный код этой статьи доступен на GitHub.