Spring Boot控制器中通过Spring Security编程实现登出并清除Cookie的方法
Spring Boot Security 控制器内手动触发登出实现方案
1. 调整WebSecurity配置
首先将登出相关组件注册为Spring Bean,方便在控制器中注入复用,修改后配置如下:
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { private static final Logger log = LoggerFactory.getLogger(WebSecurityConfig.class); @Autowired private LdapAuthenticationProvider authProvider; // 注册登出成功处理器为Bean @Bean public LogoutSuccessHandler logoutSuccessHandler() { return new HttpStatusReturningLogoutSuccessHandler(HttpStatus.OK); } // 注册默认登出处理器,自动处理上下文清除、会话销毁 @Bean public SecurityContextLogoutHandler securityContextLogoutHandler() { return new SecurityContextLogoutHandler(); } // 可选:如果需要清除指定Cookie,注册Cookie清理处理器 @Bean public CookieClearingLogoutHandler cookieClearingLogoutHandler() { return new CookieClearingLogoutHandler("JSESSIONID", "你自定义的Cookie名"); } @Override protected void configure(HttpSecurity http) throws Exception { http .authorizeRequests() .antMatchers("/css/**", "/js/**", "/images/**", "/sw.js").permitAll() .anyRequest().fullyAuthenticated() .and() .formLogin() .loginPage("/login") .permitAll() .and() .logout() .permitAll() // 引用注册的Bean,避免重复新建对象 .logoutSuccessHandler(logoutSuccessHandler()) // 可选:加入Cookie清理逻辑 .addLogoutHandler(cookieClearingLogoutHandler()); } @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.authenticationProvider(authProvider); } }
2. 修改Home控制器代码
首先在控制器中注入登出相关的Bean,然后给你的index方法添加HttpServletRequest、HttpServletResponse入参,在你标注的位置插入登出逻辑即可:
@Controller public class HomeController { @Autowired private SecurityContextLogoutHandler securityContextLogoutHandler; @Autowired private LogoutSuccessHandler logoutSuccessHandler; // 可选:注入Cookie清理处理器 @Autowired private CookieClearingLogoutHandler cookieClearingLogoutHandler; @RequestMapping("/") public String index(Principal principal, HttpServletRequest request, HttpServletResponse response) throws IsimConnectionException { Authentication authentication = (Authentication) principal; if ((authentication.getPrincipal() != null) && (authentication.isAuthenticated())) { String shortname = (String)authentication.getPrincipal(); sessionScopedLdapUser.shortname(shortname); if (isimConn.hasid()) { // --------------- 插入登出逻辑开始 --------------- // 执行默认登出逻辑:清上下文、销毁会话 securityContextLogoutHandler.logout(request, response, authentication); // 可选:执行Cookie清理 cookieClearingLogoutHandler.logout(request, response, authentication); // 触发你配置的登出成功处理器逻辑 try { logoutSuccessHandler.onLogoutSuccess(request, response, authentication); } catch (IOException | ServletException e) { // 按需处理异常 e.printStackTrace(); } // --------------- 插入登出逻辑结束 --------------- return "hasid"; } else { return "needsLinking"; } } return "index"; } }
简化方案
如果你不需要复用之前配置的logoutSuccessHandler,也可以不调整配置,直接在登出位置手动清除会话、上下文和Cookie,写法如下:
// 清除Security上下文 SecurityContextHolder.clearContext(); // 销毁会话 HttpSession session = request.getSession(false); if (session != null) { session.invalidate(); } // 清除指定Cookie Cookie cookie = new Cookie("JSESSIONID", null); cookie.setPath("/"); cookie.setMaxAge(0); response.addCookie(cookie);
上述所有实现都不需要用户主动访问/logout端点或点击登出按钮,触发逻辑完全由你自己的业务规则控制。
内容的提问来源于stack exchange,提问作者Anuska
相关产品推荐
相关产品推荐

