SpringSecurity达到最大会话数时AccessDenied事件监听实现
Spring Security 单会话限制下重复登录通知实现方案
现有配置与核心诉求
当前应用已做如下会话配置:
maximumSessions设为1sessionFixation设为none
需要实现的能力:检测到用户重复发起登录尝试时,向指定主题发送通知消息。
待确认的两个问题:- 是否可以通过监听
SessionCreationEvent,在检测到用户会话数>1时触发消息发送 - 配置
maximumSessions=1且sessionFixation=none时,是否会在首个会话存活期间阻止新会话创建
问题解答
关于监听
SessionCreationEvent实现通知的可行性
该方案不可行。SessionCreationEvent仅在会话成功创建后才会触发,而默认配置下maximumSessions=1的处理逻辑是新会话创建后自动失效同账号的旧会话,不会阻止新会话生成,此时触发通知既不符合“拦截重复登录尝试”的时机要求,也容易出现误判。关于默认配置下的新会话拦截逻辑
仅配置maximumSessions=1+sessionFixation=none时,不会阻止新会话创建。默认策略是新会话成功建立后,自动作废同账号下的原有旧会话,整个登录流程正常完成,不会抛出任何异常。
具体实现方案
方案由 @M. Deinum 提供
- 调整会话管理配置
在安全配置类的HttpSecurity配置中补充maxSessionsPreventsLogin(true)参数,配置代码片段如下:
http.sessionManagement() .maximumSessions(1) .maxSessionsPreventsLogin(true);
配置生效逻辑:
- 该参数会在内部将
ConcurrentSessionControlAuthenticationStrategy的exceptionIfMaximumExceeded属性置为true - 当同账号在首个会话存活期间发起第二次登录时,系统会直接拦截登录请求,抛出
SessionAuthenticationException,既不会创建新会话,也不会踢掉当前已经生效的原有会话。
- 实现重复登录通知逻辑
对SessionAuthenticationException做全局异常拦截,在异常处理分支中编写消息推送逻辑,向指定主题发送重复登录尝试的通知即可,可根据业务需要在通知中携带登录用户标识、请求IP、请求时间等自定义信息。
内容的提问来源于stack exchange,提问作者user1079475
相关产品推荐
相关产品推荐

