Spring Security(6)会话管理
会话管理
简单总结下springsecurity 对会话的管理配置
配置
配置 http.authorizeRequests().sessionManagement() 做配置的相关操作
1 | .and().sessionManagement(); |
会话禁用
1 | .sessionManagement().disable(); |
会话过期配置
配置过期跳转url
1
.invalidSessionUrl("/xx")
自定义过期策略
1
2
3
4
5
6invalidSessionStrategy(new InvalidSessionStrategy() {
@Override
public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
}
})
会话并发控制
实现用户只能有在一个设备上的登录的功能;
1 | .sessionManagement().maximumSessions(1); |
默认是踢掉前一个登录的人
具体实现逻辑可查看 ConcurrentSessionControlAuthenticationStrategy#onAuthentication

如果要实现后一个不能登录需要这样配置
maxSessionsPreventsLogin 禁止新用户登录
1 | .maximumSessions(1).maxSessionsPreventsLogin(true) |
实现说明
对于默认情况下的会话信息通过类 SessionRegistryImpl 进行session的存储

通过2个map维护session的相关信息;
需要注意的一点是: principals 的map的key 是 principal 也就是userdetails 对象,
在操作map的时候 使用的 也就是userdetails 是自定义的 并且未针对此场景重写hashcode 和equals 方法,那么就无法做到并发控制
因为根据当前用户信息查询所有的session的时候根据查不到,需要对userdetial做下实现能够根据用户相关的信息定义hashcode和equals
结论:自定义的userdetail 要以username 信息和重写hashcode 和equals ,因为要实现对同一个用户名的并发控制管理.
会话外部存储
注意:以上的配置在单机环境下是可以生效的,但是在集群多机器下就不一定了。因为默认的会话信息的保存是保存在jvm内存中的。
使用redis存储会话信息
需要添加spring session redis相关依赖;
1 |
|
添加redis实现的SessionRegistry
1 | @EnableRedisHttpSession |
配置到security中
1 |
|
执行等后就可以看到会话信息存储到了redis中。即使服务重启会话也没有过期;



