Spring Security 退出手動流程

Spring Security
Remote
1
05:53 AM · Nov 30 ,2025

1. 簡介

Spring Security 是用於安全 Spring 應用程序的標準。它具有管理用户身份驗證的多種功能,包括登錄和註銷。

在本教程中,我們將重點介紹使用 Spring Security 進行手動註銷。

我們假設讀者已經理解了標準的 Spring Security 註銷流程。

2. 基本登出

當用户嘗試登出時,會對當前會話狀態產生以下影響。我們需要通過以下兩個步驟銷燬會話:

  1. 無效化 HTTP 會話信息。
  2. 清除 SecurityContext,因為它包含身份驗證信息。

SecurityContextLogoutHandler 執行這兩個操作。

讓我們看看它的實際應用:

@Configuration
public class DefaultLogoutConfiguration {

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          .logout(logout -> logout
            .logoutUrl("/basic/basiclogout")
            .addLogoutHandler(new SecurityContextLogoutHandler())
          );
        return http.build();
    }
}

請注意,SecurityContextLogoutHandler 是 Spring Security 默認添加的——我們在這裏展示它以供清晰起見。

3. Cookie 清理 註銷

通常,註銷也需要清除用户的一些或全部 Cookie。

為此,我們可以創建一個 LogoutHandler,該 handler 循環遍歷所有 Cookie 並於註銷時將其過期:

@Configuration
public class AllCookieClearingLogoutConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          .logout(logout -> logout
            .logoutUrl("/cookies/cookielogout")
            .addLogoutHandler((request, response, auth) -> {
                for (Cookie cookie : request.getCookies()) {
                    String cookieName = cookie.getName();
                    Cookie cookieToDelete = new Cookie(cookieName, null);
                    cookieToDelete.setMaxAge(0);
                    response.addCookie(cookieToDelete);
                }
            })
          );
        return http.build();
    }
}

實際上,Spring Security 提供了 CookieClearingLogoutHandler,這是一個用於 Cookie 刪除的就緒式註銷 handler。

4. 清除站點數據 Header 註銷

同樣,我們可以使用特殊的 HTTP 響應頭來實現相同的功能;這裏 清除站點數據 頭部發揮作用。

基本上,清除數據站點 頭部清除與請求網站相關的瀏覽數據(cookie、存儲、緩存):

@Configuration
public class ClearSiteDataHeaderLogoutConfiguration {

    private static final 清除站點數據 寫入器. 指令[] 源 =
      {CACHE, COOKIES, STORAGE, EXECUTION_CONTEXTS};

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          .logout(logout -> logout
            .logoutUrl("/csd/csdlogout")
            .addLogoutHandler(new HeaderWriterLogoutHandler(new ClearSiteDataHeaderWriter(源)))
          );
        return http.build();
    }
}

然而, 僅清除一種存儲類型可能會導致應用程序狀態損壞。因此,由於 不完整清除,頭部僅在請求安全時才應用。

5. 請求時註銷

類似於地,我們可以使用 HttpServletRequest.logout() 方法來註銷用户。

首先,讓我們添加必要的配置以手動調用 .on the request:

@Configuration
public static class LogoutOnRequestConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.securityMatchers("/request/**")
            .authorizeHttpRequests(authz -> authz.anyRequest()
                .permitAll())
            .logout(logout -> logout.logoutUrl("/request/logout")
                .addLogoutHandler((request, response, auth) -> {
                    try {
                        request.logout();
                    } catch (ServletException e) {
                        logger.error(e.getMessage());
                    }
                }));
        return http.build();
    }
}

最後,讓我們創建一個測試用例以確認一切都按預期工作:

@Test
public void givenLoggedUserWhenUserLogoutOnRequestThenSessionCleared() throws Exception {

    this.mockMvc.perform(post("/request/logout").secure(true)
        .with(csrf()))
        .andExpect(status().is3xxRedirection())
        .andExpect(unauthenticated())
        .andReturn();
}

6. 結論

總而言之,Spring Security 提供了許多內置功能來處理身份驗證場景。 熟練掌握如何通過編程方式使用這些功能始終非常實用。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.