Spring Security OAuth2.0(10):登出

退出

Spring security 默认实现了logout 退出,访问/logout ,即可直接退出。

http://localhost:8080/security-springboot/logout

退出后,可以通过访问其他url 判断是否退出成功。

如何自定义退出

在Spring Security中自定义退出(Logout)功能,主要通过配置SecurityConfig中的logout()相关方法实现。以下是详细步骤和示例代码:

1. 基础配置:自定义退出路径和重定向

通过LogoutConfigurer配置退出路径、退出成功后的重定向地址及需要清除的凭证(如Cookie、Session):

java 复制代码
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            .logout()
                .logoutUrl("/custom-logout")      // 自定义退出请求路径(默认/logout)
                .logoutSuccessUrl("/login")       // 退出成功后重定向的页面
                .invalidateHttpSession(true)      // 使Session失效(默认true)
                .deleteCookies("JSESSIONID")      // 删除指定Cookie
                .and()
            // ...其他配置(如授权、认证等)
    }
}

2. 添加自定义退出逻辑(如日志、业务操作)

通过addLogoutHandler()或logoutSuccessHandler()实现退出前/后的自定义逻辑:

java 复制代码
http
    .logout()
        .logoutUrl("/custom-logout")
        .addLogoutHandler(customLogoutHandler())  // 退出前执行(如清理Token)
        .logoutSuccessHandler(customSuccessHandler()) // 退出后处理(如返回JSON)

// 示例:自定义LogoutHandler(清理用户Token)
@Bean
public LogoutHandler customLogoutHandler() {
    return (request, response, authentication) -> {
        // 获取当前用户Token并标记失效(需结合具体Token存储方案)
        String token = request.getHeader("Authorization");
        tokenService.invalidateToken(token);
    };
}

// 示例:自定义LogoutSuccessHandler(返回JSON响应)
@Bean
public LogoutSuccessHandler customSuccessHandler() {
    return (request, response, authentication) -> {
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write("{\"code\":200, \"msg\":\"退出成功\"}");
    };
}

3. 集成CSRF保护(默认启用)

退出请求默认需要CSRF Token验证。前端需在退出请求中携带X-CSRF-TOKEN(可从Cookie或Meta标签获取),或在配置中禁用CSRF(不推荐):

java 复制代码
http
    .csrf().disable() // 禁用CSRF(仅测试环境使用)
  • 注意:如果让logout在GET请求下生效,必须关闭防止CSRF攻击csrf().disable() 。如果开启了CSRF,必须使用post方式请求/logout

4. 处理并发会话退出

若需强制用户在其他终端的会话退出,可结合SessionRegistry:

java 复制代码
@Autowired
private SessionRegistry sessionRegistry;

http
    .sessionManagement()
        .maximumSessions(1)          // 最大会话数
        .sessionRegistry(sessionRegistry)
    .and()
    .logout()
        .logoutUrl("/custom-logout")
        .logoutSuccessHandler((request, response, authentication) -> {
            // 强制所有会话退出
            new SecurityContextLogoutHandler().logout(request, response, authentication);
            sessionRegistry.getAllSessions(authentication.getName(), false)
                .forEach(sessionInformation -> sessionInformation.expireNow());
        })

5. 退出时清除自定义安全上下文

若使用自定义SecurityContext(如存储额外用户信息),需在退出时手动清理:

java 复制代码
http
    .logout()
        .logoutUrl("/custom-logout")
        .addLogoutHandler((request, response, authentication) -> {
            SecurityContextHolder.clearContext(); // 清除安全上下文
        })

logoutHandler:

一般来说,LogoutHandler的实现类被用来执行必要的清理,因而他们不应该抛出异常。

下面是Spring Security提供的一些实现:

  • PersistentTokenBasedRememberMeServices 基于持久化token的RememberMe功能的相关清理
  • TokenBasedRememberMeService 基于token的RememberMe功能的相关清理
  • CookieClearingLogoutHandler 退出时Cookie的相关清理
  • CsrfLogoutHandler 负责在退出时移除csrfToken
  • SecurityContextLogoutHandler 退出时SecurityContext的相关清理

常见问题解决

  • 退出后仍能访问受保护资源:检查是否清除了Session/Cookie,或重定向路径是否正确。
  • CSRF Token缺失 :确保前端退出请求携带有效Token,或配置http.csrf().csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse())。
  • Token未失效 :在自定义LogoutHandler中实现Token黑名单机制(如Redis存储失效Token)。

通过以上配置,可灵活实现退出路径定制、业务逻辑扩展、会话管理及安全凭证清理。具体实现需结合项目使用的认证方式(如Session、JWT、OAuth2)调整细节。

相关推荐
学长毕设43 分钟前
基于springboot的食品仓库管理系统
java·spring boot·后端
滴滴答答哒1 小时前
ASP.NET Core + FaceRecognitionDotNet 人脸识别实战:DI 单例、特征向量持久化与 1:N 比对
后端·asp.net
步行cgn1 小时前
FormHttpMessageConverter 详解:Spring MVC 中表单数据的读写转换器
java·spring·mvc
龙亘川1 小时前
构建城市公共安全数字底座:亘川智城智慧安防系统全维度解读
java·大数据·开发语言·人工智能·信息可视化
金銀銅鐵1 小时前
[Java] 用 CLI 展示 EnumMap 增删键值对时的内部变化
java·源码·ai编程
秋天的怀念_David2 小时前
第二十二夜 · 数字迷雾
java·程序人生·算法
Raas1002 小时前
AI网关部署方案?从部署到上线全流程
java·开发语言·人工智能·gateway·ai网关·企业级ai网关·企业级ai产品
niucloud-admin3 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
霸道流氓气质3 小时前
智能客服组件:分层意图识别、RAG Advisor 与人工转接状态机的 Vue3 + Spring AI 生产级实战
java·人工智能·spring
captain3764 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis