案例1:当用户在第2台电脑登录时,第1台电脑抛出错误信息,并下线
| .and() |
| .sessionManagement() |
| |
| .maximumSessions(1) |
| public class CustomSessionInformationExpiredStrategy implements SessionInformationExpiredStrategy { |
| |
| |
| @Autowired |
| CustomAuthenticationFailureHandler customAuthenticationFailureHandler; |
| |
| @Override |
| public void onExpiredSessionDetected(SessionInformationExpiredEvent event) throws IOException { |
| |
| UserDetails userDetails = |
| (UserDetails)event.getSessionInformation().getPrincipal(); |
| |
| AuthenticationException exception = |
| new AuthenticationServiceException( |
| String.format("[%s] 用户在另外一台电脑登录,您已被下线", userDetails.getUsername())); |
| try { |
| |
| event.getRequest().setAttribute("toAuthentication" , true); |
| |
| customAuthenticationFailureHandler |
| .onAuthenticationFailure(event.getRequest(), event.getResponse(), exception); |
| } catch (ServletException e) { |
| e.printStackTrace(); |
| } |
| } |
| |
| } |
| @Component("customAuthenticationFailureHandler") |
| public class CustomAuthenticationFailureHandler implements AuthenticationFailureHandler { |
| |
| |
| |
| |
| @Override |
| public void onAuthenticationFailure(HttpServletRequest request, |
| HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException { |
| |
| MengxueguResult result = MengxueguResult.build(HttpStatus.UNAUTHORIZED.value(), exception.getMessage()); |
| response.setContentType("application/json;charset=UTF-8"); |
| response.getWriter().write(result.toJsonString()); |
| System.out.println("CustomAuthenticationFailureHandler ---> error"); |
| |
| Object toAuthentication = request.getAttribute("toAuthentication"); |
| if (toAuthentication != null) { |
| error1(); |
| } else { |
| error2(); |
| } |
| } |
| |
| public void error1() { |
| System.out.println("当前为用户在多台电脑登录抛出的异常!"); |
| } |
| |
| public void error2() { |
| System.out.println("当前为用户认证失败抛出的异常!"); |
| } |
| |
| } |
| @Configuration |
| public class SecurityConfigBean { |
| |
| |
| |
| |
| |
| |
| |
| |
| @Bean |
| @ConditionalOnMissingBean(SessionInformationExpiredStrategy.class) |
| public SessionInformationExpiredStrategy sessionInformationExpiredStrategy() { |
| return new CustomSessionInformationExpiredStrategy(); |
| } |
| |
| } |
| |
| @Autowired |
| private SessionInformationExpiredStrategy sessionInformationExpiredStrategy; |
| |
| |
| .and() |
| .sessionManagement() |
| |
| .maximumSessions(1) |
| |
| .expiredSessionStrategy(sessionInformationExpiredStrategy) |
- 测试2:用edge浏览器模拟第1台电脑,用谷歌浏览器模拟第2台电脑,在edge浏览器认证成功后,再去谷歌浏览器认证,谷歌浏览器认证成功后,刷新edge浏览器,提示如下错误信息

| # 控制台打印入下 |
| 11:55:13.397 INFO 19888 |
| CustomAuthenticationFailureHandler |
| 当前为用户在多台电脑登录抛出的异常! |
- 测试认证失败:认证时输入错误的用户名和密码

| # 控制台打印如下 |
| 12:12:51.770 INFO 19888 |
| CustomAuthenticationFailureHandler |
| 当前为用户认证失败抛出的异常! |
案例2:当用户在第1台电脑认证成功后,再在第2台电脑登录,这是不允许在第2台电脑登录
使用记住我功能时,不能设置maxSessionsPreventsLogin(true)
- 在security配置类中配置如下
| .and() |
| .sessionManagement() |
| |
| .maximumSessions(1) |
| |
| .expiredSessionStrategy(sessionInformationExpiredStrategy) |
| .maxSessionsPreventsLogin(true) |
- 测试:在edge浏览器认证成功,之后在联想浏览器认证

| # 控制台打印如下 |
| 13:14:04.169 INFO 23736 |
| CustomAuthenticationFailureHandler |
| 当前为用户认证失败抛出的异常! |
案例3:只允许1台电脑登录;第1台电脑使用用户名+密码登录,设置第2台电脑不能使用用户名+密码或手机号+短信
- 如果在当前项目中可以使用用户名+密码认证,也可以使用手机号+验证码认证;在设置了不允许第2台电脑登录的情况下,第1台电脑使用用户名+密码认证,第2台电脑使用手机号+短信认证也能认证,正确逻辑是第2台电脑既不能使用用户名+密码认证,也不能使用手机号+短信认证,说明之前设置的只允许1台电脑登录无效
| # 在MobileAuthenticationConfig中配置如下 |
| |
| mobileAuthenticationFilter.setSessionAuthenticationStrategy(http.getSharedObject(SessionAuthenticationStrategy.class)); |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术