springSecurity2.7.9 实现“用户在另外一台电脑登录,您已被下线“的效果

首先确保springSecurity的版本是2.7.9

第一步:配置filterChain()方法

java 复制代码
				.and()
                .sessionManagement()
                // 设置一个session最多只能有一个用户使用,默认是无限制
                .maximumSessions(1)
                .sessionRegistry(sessionRegistry)
                .expiredSessionStrategy(sessionInformationExpiredStrategy);

.maximumSessions(1): 设置一个会话最多只能有一个用户使用。这意味着当一个用户已经登录并且会话尚未过期时,如果另一个用户尝试使用相同的凭据登录,先前的会话将被失效。

.sessionRegistry(sessionRegistry): 设置一个用于跟踪活动会话的SessionRegistry对象。SessionRegistry用于管理和访问当前活动会话的信息。

java 复制代码
    @Resource
    private SessionRegistry sessionRegistry;

.expiredSessionStrategy(sessionInformationExpiredStrategy): 设置一个会话过期策略。当会话过期时,将采取特定的操作。sessionInformationExpiredStrategy是一个实现了SessionInformationExpiredStrategy接口的自定义策略对象,用于定义会话过期后的处理逻辑。

通过以上配置,可以实现对会话的最大并发控制和会话过期处理.

第二步:重写SessionInformationExpiredStrategy中的onExpiredSessionDetected方法,自定义会话过期策略

java 复制代码
public class MySessionInformationExpiredStrategy implements SessionInformationExpiredStrategy {

    private static final Logger logger = LogManager.getLogger(MySessionInformationExpiredStrategy.class);

    @Resource
    AuthenticationFailureHandlerImp authenticationFailureHandlerImp;

    @Override
    public void onExpiredSessionDetected(SessionInformationExpiredEvent event) {
        // 1. 获取用户名
        UserDetails userDetails = (UserDetails) event.getSessionInformation().getPrincipal();
        AuthenticationException exception = new AuthenticationServiceException(
                String.format("[%s]用户在另外一台电脑登录,您已被下线", userDetails.getUsername()));
        try {
            // 当用户在另外一台电脑登录后,交给失败处理器回到认证页面
            event.getRequest().setAttribute("toAuthentication" , true);
            authenticationFailureHandlerImp.onAuthenticationFailure(event.getRequest(),event.getResponse(),exception);
        }catch (Exception e){
            logger.error("MySessionInformationExpiredStrategy->onExpiredSessionDetected:{}", e.getMessage());
        }
    }


}

第三步:把SessionRegistry和SessionInformationExpiredStrategy注册到springboot中交由springboot管理

java 复制代码
@Configuration
public class Config {

    @Bean
    @ConditionalOnMissingBean(SessionInformationExpiredStrategy.class)
    public SessionInformationExpiredStrategy informationExpiredStrategy() {
        return new MySessionInformationExpiredStrategy();
    }

    @Bean
    public SessionRegistry sessionRegistry() {
        return new SessionRegistryImpl();
    }
}

第四步:在AuthenticationFailureHandler方法定义一下,springSecurity的登录失败回调方法

我是这样写的,比较粗糙

java 复制代码
@Component
public class AuthenticationFailureHandlerImp implements AuthenticationFailureHandler {
    private static final Logger logger = LogManager.getLogger(AuthenticationFailureHandlerImp.class);
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response
            , AuthenticationException exception) throws IOException, ServletException {
            response.setContentType("application/json;charset=utf-8");
        if (exception.getMessage().indexOf("您已被下线") !=0) {
            response.setStatus(400);
            response.getWriter().append(ResponseStatus.createFailureStatus(exception.getMessage()).toString());
        }else {
            response.setStatus(403);
            response.getWriter().append(ResponseStatus.createFailureStatus("登录失败").toString());
        }
        logger.error("AuthenticationFailureHandlerImp: {}", exception.getMessage());
    }
}

结束:
A用户在A电脑上登录,之后A用户又在B电脑上登录,这个时候,A电脑在去访问我们的后端接口就会提示"A用户在另外一台电脑登录,您已被下线",还没有做到实时通知,感兴趣的可以自己实现一下

相关推荐
JH30734 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
Coder_Boy_5 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble6 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟6 小时前
使用ASM和agent监控属性变化
java
黎雁·泠崖6 小时前
【魔法森林冒险】5/14 Allen类(三):任务进度与状态管理
java·开发语言
qq_12498707537 小时前
基于SSM的动物保护系统的设计与实现(源码+论文+部署+安装)
java·数据库·spring boot·毕业设计·ssm·计算机毕业设计
Coder_Boy_7 小时前
基于SpringAI的在线考试系统-考试系统开发流程案例
java·数据库·人工智能·spring boot·后端
Mr_sun.7 小时前
Day06——权限认证-项目集成
java
瑶山8 小时前
Spring Cloud微服务搭建四、集成RocketMQ消息队列
java·spring cloud·微服务·rocketmq·dashboard
abluckyboy8 小时前
Java 实现求 n 的 n^n 次方的最后一位数字
java·python·算法