博客
关于我
Spring Security 实战干货:实现自定义退出登录
阅读量:419 次
发布时间:2019-03-06

本文共 3510 字,大约阅读时间需要 11 分钟。

Spring Security 退出登录实战

前言

上一篇对 Spring Security 所有内置的进行了介绍。今天我们来实战如何安全退出应用程序。


登录后的处理

登录后,服务端会给用户发一个凭证。常见有以下两种:

  • 基于 Session:服务端存一个 Session,客户端存 cookie。
  • 基于 token:客户端存 token,服务端存校验信息。

  • 退出登录需要做什么

  • 清除服务端的用户状态。
  • 退出登录接口不是 permitAll,只有携带对应用户的凭证才退出。
  • 将退出结果返回给请求方。
  • 退出后用户可以通过重新登录来认证。

  • Spring Security 中的退出登录

    接下来我们分析并实战如何定制退出登录逻辑。


    3.1 LogoutFilter

    退出登录逻辑由过滤器 LogoutFilter 执行。它持有三个接口属性:

  • RequestMatcher logoutRequestMatcher:拦截退出请求的 URL。
  • LogoutHandler handler:处理退出逻辑。
  • LogoutSuccessHandler logoutSuccessHandler:退出成功后执行逻辑。

  • 3.2 LogoutConfigurer

    我们通过 HttpSecurity#logout() 初始化 LogoutConfigurer。接下来实战配置。

    3.2.1 自定义退出登录请求 URL

    LogoutConfigurer 提供两种方式定义退出 URL:logoutRequestMatcher 和 logoutUrl。选择其中一种即可。

    3.2.2 处理具体逻辑

    默认情况下 Spring Security 是基于 Session 的。LogoutConfigurer 提供清除认证信息、删除 cookies、移除 HttpSession 等功能。如果不满足需求,需定制 LogoutHandler 和 LogoutSuccessHandler。

    3.2.3 退出成功逻辑

  • logoutSuccessUrl:退出成功后重定向的 URL。你可以写一个Controller完成,最终返回,需支持 GET 请求和匿名访问。
  • defaultLogoutSuccessHandlerFor:构造默认 LogoutSuccessHandler,可以实现不同 URL 的逻辑。
  • LogoutSuccessHandler:退出成功后执行的逻辑的抽象接口。

  • 3.3 Spring Security 退出登录实战

    现在前后端分离,退出后返回 json。且只有用户在线才能退出。我们采用 LogoutHandler 和 LogoutSuccessHandler 编程方式配置退出逻辑。


    3.3.1 自定义 LogoutHandler

    默认情况下清除认证信息和 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);    }}

    3.3.2 自定义 LogoutSuccessHandler

    如果实现了自定义 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();    }}

    3.3.4 自定义退出的 Spring Security 配置

    为了方便调试注释掉了部分配置。你可以通过 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/

    你可能感兴趣的文章
    OpenCV与AI深度学习 | 如何使用YOLOv9分割图像中的对象
    查看>>
    OpenCV与AI深度学习 | 如何使用YOLOv9检测图片和视频中的目标
    查看>>
    OpenCV与AI深度学习 | 如何在 Docker 容器中使用 GPU
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV中更稳更快的找圆方法--EdgeDrawing使用演示(详细步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV传统方法实现密集圆形分割与计数(详细步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | OpenCV实现扫描文本矫正应用与实现详解(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用OpenCV和Streamlit搭建虚拟化妆应用程序(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用OpenCV确定对象的方向(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用YOLOv8 Pose实现瑜伽姿势识别
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用YoloV8实例分割识别猪的姿态(含数据集)
    查看>>
    OpenCV与AI深度学习 | 实战 | 使用姿态估计算法构建简单的健身训练辅助应用程序
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于OpenCV和K-Means聚类实现颜色分割(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YoloV5和Mask RCNN实现汽车表面划痕检测(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YOLOv9+SAM实现动态目标检测和分割(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 基于YOLOv9和OpenCV实现车辆跟踪计数(步骤 + 源码)
    查看>>
    OpenCV与AI深度学习 | 实战 | 文本图片去水印--同时保持文本原始色彩(附源码)
    查看>>
    OpenCV与AI深度学习 | 实战—使用YOLOv8图像分割实现路面坑洞检测(步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战篇——基于YOLOv8和OpenCV实现车速检测(详细步骤 + 代码)
    查看>>
    OpenCV与AI深度学习 | 实战|OpenCV实时弯道检测(详细步骤+源码)
    查看>>
    OpenCV与AI深度学习 | 实践教程|旋转目标检测模型-TensorRT 部署(C++)
    查看>>