本文共 3510 字,大约阅读时间需要 11 分钟。
上一篇对 Spring Security 所有内置的进行了介绍。今天我们来实战如何安全退出应用程序。
登录后,服务端会给用户发一个凭证。常见有以下两种:
接下来我们分析并实战如何定制退出登录逻辑。
退出登录逻辑由过滤器 LogoutFilter 执行。它持有三个接口属性:
我们通过 HttpSecurity#logout() 初始化 LogoutConfigurer。接下来实战配置。
LogoutConfigurer 提供两种方式定义退出 URL:logoutRequestMatcher 和 logoutUrl。选择其中一种即可。
默认情况下 Spring Security 是基于 Session 的。LogoutConfigurer 提供清除认证信息、删除 cookies、移除 HttpSession 等功能。如果不满足需求,需定制 LogoutHandler 和 LogoutSuccessHandler。
现在前后端分离,退出后返回 json。且只有用户在线才能退出。我们采用 LogoutHandler 和 LogoutSuccessHandler 编程方式配置退出逻辑。
默认情况下清除认证信息和 Session 已经由 SecurityContextLogoutHandler 完成。我们自定义 LogoutHandler 会在其基础上执行。
@Slf4jpublic class CustomLogoutHandler implements LogoutHandler { @Override public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) { User user = (User) authentication.getPrincipal(); String username = user.getUsername(); log.info("username: {} is offline now", username); }} 如果实现了自定义 LogoutSuccessHandler,就不需要设置 logoutSuccessUrl。处理后会响应给前端。你可以转发到其他控制器,或者实现其他 MediaType,比如 json 或页面。
@Slf4jpublic class CustomLogoutSuccessHandler implements LogoutSuccessHandler { @Override public void onLogoutSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException, ServletException { User user = (User) authentication.getPrincipal(); String username = user.getUsername(); log.info("username: {} is offline now", username); responseJsonWriter(response, RestBody.ok("退出成功")); } private static void responseJsonWriter(HttpServletResponse response, Rest rest) throws IOException { response.setStatus(HttpServletResponse.SC_OK); response.setCharacterEncoding("utf-8"); response.setContentType(MediaType.APPLICATION_JSON_VALUE); ObjectMapper objectMapper = new ObjectMapper(); String resBody = objectMapper.writeValueAsString(rest); PrintWriter printWriter = response.getWriter(); printWriter.print(resBody); printWriter.flush(); printWriter.close(); }} 为了方便调试注释掉了部分配置。你可以通过 http:localhost:8080/login 登录,然后通过 http:localhost:8080/logout 测试退出。
@Overrideprotected void configure(HttpSecurity http) throws Exception { http.csrf().disable() .cors() .and() .authorizeRequests().anyRequest().authenticated() .and() .formLogin().loginProcessingUrl(LOGIN_PROCESSING_URL).successForwardUrl("/login/success").failureForwardUrl("/login/failure") .and().logout() .addLogoutHandler(new CustomLogoutHandler()) .logoutSuccessHandler(new CustomLogoutSuccessHandler());} 本篇实现了 Spring Security 下的自定义退出逻辑。相对比较简单,你可以根据你的业务需要来实现你的退出逻辑。有什么疑问可以通过关注公众号 Felordcn 私信提问。相关DEMO代码也可以通过关注后回复 ss04 获取。
转载地址:http://xpjuz.baihongyu.com/