Spring Security 实战内容:实现自定义退出登录
1. 前言
今天我们来实战如何安全退出应用程序。
2. 我们使用 Spring Security 登录后都做了什么
这个问题我们必须搞清楚!一般登录后,服务端会给用户发一个凭证。常见有以下的两种:
基于
Session
客户端会存cookie
来保存一个sessionId
,服务端存一个Session
。基于
token
客户端存一个token
串,服务端会在缓存中存一个用来校验此token
的信息。
2. 退出登录需要我们做什么
- 当前的用户登录状态失效。这就需要我们清除服务端的用户状态。
- 退出登录接口并不是
permitAll
, 只有携带对应用户的凭证才退出。 - 将退出结果返回给请求方。
- 退出登录后用户可以通过重新登录来认证该用户。
3. Spring Security 中的退出登录
接下来我们来分析并实战 如何定制退出登录逻辑。首先我们要了解 LogoutFilter
。
3.1 LogoutFilter
我们知道退出登录逻辑是由过滤器 LogoutFilter
来执行的。 它持有三个接口类型的属性:
RequestMatcher logoutRequestMatcher
这个用来拦截退出请求的URL
LogoutHandler handler
用来处理退出的具体逻辑LogoutSuccessHandler logoutSuccessHandler
退出成功后执行的逻辑
我们通过对以上三个接口的实现就能实现我们自定义的退出逻辑。
3.2 LogoutConfigurer
我们一般不会直接操作 LogoutFilter
,而是通过 LogoutConfigurer
来配置 LogoutFilter
。 你可以通过 HttpSecurity#logout()
方法来初始化一个 LogoutConfigurer
。 接下来我们来实战操作一下。
3.2.1 实现自定义退出登录请求URL
LogoutConfigurer
提供了 logoutRequestMatcher(RequestMatcher logoutRequestMatcher)
、logoutUrl(Sring logoutUrl)
两种方式来定义退出登录请求的 URL
。它们作用是相同的,你选择其中一种方式即可。
3.2.2 处理具体的逻辑
默认情况下 Spring Security 是基于 Session
的。LogoutConfigurer
提供了一些直接配置来满足你的需要。如下:
clearAuthentication(boolean clearAuthentication)
是否在退出时清除当前用户的认证信息deleteCookies(String... cookieNamesToClear)
删除指定的cookies
invalidateHttpSession(boolean invalidateHttpSession)
是否移除HttpSession
如果上面满足不了你的需要就需要你来定制 LogoutHandler
了。
3.2.3 退出成功逻辑
logoutSuccessUrl(String logoutSuccessUrl)
退出成功后会被重定向到此URL
,你可以写一个Controller 来完成最终返回,但是需要支持GET
请求和 匿名访问 。 通过setDefaultTargetUrl
方法注入到LogoutSuccessHandler
defaultLogoutSuccessHandlerFor(LogoutSuccessHandler handler, RequestMatcher preferredMatcher)
用来构造默认的LogoutSuccessHandler
我们可以通过添加多个来实现从不同URL
退出执行不同的逻辑。LogoutSuccessHandler logoutSuccessHandler
退出成功后执行的逻辑的抽象根本接口。
3.3 Spring Security 退出登录实战
现在前后端分离比较多,退出后返回json。 而且只有用户在线才能退出登录。否则不能进行退出操作。我们采用实现 LogoutHandler
和 LogoutSuccessHandler
接口这种编程的方式来配置 。退出请求的 url
依然通过 LogoutConfigurer#logoutUrl(String logoutUrl)
来定义。
3.3.1 自定义 LogoutHandler
默认情况下清除认证信息 (invalidateHttpSession
),和Session 失效(invalidateHttpSession
) 已经由内置的SecurityContextLogoutHandler
来完成。我们自定义的 LogoutHandler
会在SecurityContextLogoutHandler
来执行。
@Slf4jpublic class CustomLogoutHandler implements LogoutHandler {@Overridepublic void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {User user = (User) authentication.getPrincipal();String username = user.getUsername();log.info("username: {} is offline now", username);}}
以上是我们实现的 LogoutHandler
。 我们可以从 logout
方法的 authentication
变量中 获取当前用户信息。你可以通过这个来实现你具体想要的业务。比如记录用户下线退出时间、IP 等等。
3.3.2 自定义 LogoutSuccessHandler
如果我们实现了自定义的 LogoutSuccessHandler
就不必要设置 LogoutConfigurer#logoutSuccessUrl(String logoutSuccessUrl)
了。该处理器处理后会响应给前端。你可以转发到其它控制器。重定向到登录页面,也可以自行实现其它 MediaType
,可以是 json
或者页面
@Slf4jpublic class CustomLogoutSuccessHandler implements LogoutSuccessHandler {@Overridepublic 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()// .addFilterBefore(preLoginFilter, UsernamePasswordAuthenticationFilter.class)// 登录.formLogin().loginProcessingUrl(LOGIN_PROCESSING_URL).successForwardUrl("/login/success").failureForwardUrl("/login/failure").and().logout().addLogoutHandler(new CustomLogoutHandler()).logoutSuccessHandler(new CustomLogoutSuccessHandler());}
4. 总结
本篇 我们实现了 在 Spring Security 下的自定义退出逻辑。相对比较简单,你可以根据你的业务需要来实现你的退出逻辑。
只要一步一个脚印,水滴石穿,吃透、搞懂、拿捏住是完全没有问题的!看到这里的都是妥妥的铁粉无疑了,底下是交流群找到的可是有大把源码,学习路线思维导图啥的,多的我就不透露,124388967看大家自己的积极性了啊,热爱所热爱的, 学习伴随终生
Spring Security 实战内容:实现自定义退出登录相关推荐
- Spring Security 实战:实现自定义退出登录
1. 前言 上一篇对 Spring Security 所有内置的 Filter 进行了介绍.今天我们来实战如何安全退出应用程序. 2. 我们使用 Spring Security 登录后都做了什么 这个 ...
- Spring Security 实战干货:自定义异常处理
Spring Security 实战干货:自定义异常处理 转自:https://www.cnblogs.com/felordcn/p/12142514.html 文章目录 1. 前言 2. Sprin ...
- Spring Security 实战干货:自定义配置类入口 WebSecurityConfigurerAdapter
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 今天我们要进一步的的学习如何自定义配置 Sp ...
- Spring Security 实战:自定义异常处理
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 最近实在比较忙,很难抽出时间来继续更 [S ...
- Spring Security 实战:基于配置的接口角色访问控制
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 码农小胖哥 来源 | 公众号「码农小胖哥」 1 ...
- Spring Security 实战:使用 JWT 认证访问接口
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 欢迎阅读Spring Security 实战 ...
- Spring Security 实战干货: RBAC权限控制概念的理解
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 码农小胖哥 来源 | 公众号「码农小胖哥」 1 ...
- Spring Security 实战干货:玩转自定义登录
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 前面的关于 Spring Security ...
- Spring Security 实战干货:实现自定义退出登录
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 1. 前言 上一篇对 Spring Security 所 ...
最新文章
- 过桥问题c语言程序,盏灯过桥游戏
- oracle更改密码机制,Oracle密码机制以及常用操作
- Java小故事(一)
- java hashmapconcurrentHashmap源理
- java如何保证类不被回收_垃圾回收机制保证了Java程序不会出现内存溢出。( )
- 怎么看电脑是不是linux系统,怎么查看自己的电脑系统是什么版本
- qt调用仪器驱动库dll实现程控
- helperdialect mysql_Mybatis使用pageHelper步骤(动态分页)
- c语言分号应用,问什么C程序里总是提示缺少分号;,而明明有分号?
- 【JAVA】每日练习——01
- 贝叶斯分析好坏_浅析贝叶斯定理及其应用
- Odoo12功能增强模块
- 终于知道为啥网页不让我复制粘贴了!
- 【第42期】游戏策划:如何让游戏帮助孩子成长?
- 蓝蓝算法09-进制转换
- 工作流(Flowable)
- 使用豆瓣镜像下载软件
- win10无法连接校园网问题
- 旧金山市交通系统遭勒索软件感染细节进一步公布
- Idea Lambda expressions are not supported at language level '5'