我在并发会话管理中遇到一些问题,尤其是在执行多个并发请求时。使用此配置:
http
.sessionManagement()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.maximumSessions(1)
.sessionRegistry(sessionRegistry)
.maxSessionsPreventsLogin(true)
给定的用户一次只能创建一个会话。它可以工作,但是当我尝试使用多个线程多次登录时,将绕过ConcurrentSessionControlAuthenticationStrategy
执行的检查。从实现的角度看,此类的设计似乎并未考虑线程安全性:
final List<SessionInformation> sessions = sessionRegistry.getAllSessions(
authentication.getPrincipal(), false);
int sessionCount = sessions.size();
int allowedSessions = getMaximumSessionsForThisUser(authentication);
if (sessionCount < allowedSessions) {
// They haven't got too many login sessions running at present
return;
}
if (allowedSessions == -1) {
// We permit unlimited logins
return;
}
使用方面将会话身份验证策略包装在同步块中可以解决此问题,但我想知道是否有更好的方法(或者我错过了一些配置)。
我创建了一个Spring Boot示例应用程序,用于重现此GitHub repository中的错误。主要类是PeakTest
和force-sync
属性(请注意,由于测试的不确定性,结果在两次运行之间会发生变化)。
预先感谢