1. 概述
本教程將深入探討如何禁用 Spring Security 中的登出重定向的方法。
首先,我們將簡要介紹 Spring Security 中登出流程的工作原理。然後,我們將通過一個實際示例,演示如何在成功登出後避免用户重定向。
2. 在 Spring Security 中註銷
簡而言之,Spring Security 通過 logout() DSL 方法提供內置的註銷機制支持。基本上,Spring Security 在用户訪問默認註銷 URL 時觸發註銷,該 URL 為 /logout.
值得一提的是,默認註銷 URL 的值在 Spring Security 4 之前為 /j_spring_security_logout。
Spring Security 提供了一種將用户重定向到特定 URL 的可能性,在註銷後。然而,在某些情況下,我們可能希望避免這種行為。
那麼,不廢話,讓我們看看如何在 Spring Security 中實現禁用註銷重定向的邏輯。
3. 禁用 Spring Security 註銷重定向
默認情況下,Spring Security 在成功註銷後會將用户重定向到 `/login?logout </em/>。因此,本節將重點介紹如何防止用户在註銷後重定向到登錄頁面。
請注意,我們可以藉助 `.logoutSuccessUrl() </em/> DSL 方法來覆蓋默認重定向 URL。
主要目的是展示如何在從 REST 客户端調用 `/logout </em/> URL 時避免重定向。
事實上,`Log</em/>outSuccessHandler</em/> 接口提供了一種靈活的方式,可以在註銷過程成功執行時執行自定義邏輯。
因此,我們將 使用自定義的 `LogoutSuccessHandler</em/> 以僅返回乾淨的 200 狀態碼。 這樣就不會將我們重定向到任何頁面。
現在,讓我們實現必要的 Spring Security 配置,以禁用註銷重定向:
@Configuration
@EnableWebSecurity
public class SpringSecurityConfig {
@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
http.authorizeHttpRequests(authz -> authz.requestMatchers("/login")
.permitAll()
.anyRequest()
.authenticated())
.logout(logout -> logout.permitAll()
.logoutSuccessHandler((request, response, authentication) -> {
response.setStatus(HttpServletResponse.SC_OK);
}));
return http.build();
}
}需要注意的是,上述配置中最重要的部分是 logoutSuccessHandler() 方法。正如我們所見,我們使用 lambda 表達式來定義我們的自定義註銷成功處理器。
請記住,我們還可以創建 LogoutSuccessHandler 接口的簡單實現類,並使用 DSL 將其傳遞給 logoutSuccessHandler() 方法。
4. 測試
現在我們已經將所有組件整合在一起,讓我們測試 /logout 端點,以確認一切都按預期工作。
請注意,我們將使用 <em >MockMvc</em> 發送 /logout 請求,在我們的測試中。
首先,讓我們創建一個簡單的測試類並將其注入 <em >MockMvc</em> 對象:
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 響應的 body
5. 結論
總結來説,我們已經解釋並説明了如何解決 Spring Security 和 Spring Boot 中禁用登出重定向的挑戰。