博客
关于我
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/

    你可能感兴趣的文章
    NFS网络文件系统
    查看>>
    nft文件传输_利用remoting实现文件传输-.NET教程,远程及网络应用
    查看>>
    NFV商用可行新华三vBRAS方案实践验证
    查看>>
    ng build --aot --prod生成文件报错
    查看>>
    ng 指令的自定义、使用
    查看>>
    nghttp3使用指南
    查看>>
    Nginx
    查看>>
    nginx + etcd 动态负载均衡实践(三)—— 基于nginx-upsync-module实现
    查看>>
    nginx + etcd 动态负载均衡实践(二)—— 组件安装
    查看>>
    nginx + etcd 动态负载均衡实践(四)—— 基于confd实现
    查看>>
    Nginx + Spring Boot 实现负载均衡
    查看>>
    Nginx + uWSGI + Flask + Vhost
    查看>>
    Nginx - Header详解
    查看>>
    Nginx - 反向代理、负载均衡、动静分离、底层原理(案例实战分析)
    查看>>
    nginx 1.24.0 安装nginx最新稳定版
    查看>>
    nginx 301 永久重定向
    查看>>
    nginx css,js合并插件,淘宝nginx合并js,css插件
    查看>>
    Nginx gateway集群和动态网关
    查看>>
    Nginx Location配置总结
    查看>>
    Nginx log文件写入失败?log文件权限设置问题
    查看>>