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用户在另外一台电脑登录,您已被下线",还没有做到实时通知,感兴趣的可以自己实现一下

相关推荐
2201_757830874 小时前
全局异常处理器
java
小徐Chao努力5 小时前
【Langchain4j-Java AI开发】09-Agent智能体工作流
java·开发语言·人工智能
Coder_Boy_5 小时前
SpringAI与LangChain4j的智能应用-(理论篇2)
人工智能·spring boot·langchain·springai
Coder_Boy_5 小时前
SpringAI与LangChain4j的智能应用-(理论篇3)
java·人工智能·spring boot·langchain
Coder_Boy_5 小时前
基于SpringAI的智能平台基座开发-(六)
java·数据库·人工智能·spring·langchain·langchain4j
武昌库里写JAVA6 小时前
iview-CRUD模板
vue.js·spring boot·sql·layui·课程设计
伯明翰java6 小时前
Java数据类型与变量
java·开发语言
想用offer打牌6 小时前
如何开启第一次开源贡献之路?
java·后端·面试·开源·github
小许学java7 小时前
Spring原理
java·spring·生命周期·作用域·原理
教练、我想打篮球7 小时前
122 Hession,FastJson,ObjectInputStream的序列化反序列化相同引用的处理
java·config·utils