Spring Boot中并发会话和OAuth2的问题



我正在使用Spring Security 5.6.0和OAuth 2.0身份验证。我试图将每个用户的并发会话限制为一个。经过几次尝试,我终于写下了以下代码:

@Override
protected void configure(HttpSecurity http) throws Exception {
http
[...]
.sessionManagement()
.sessionFixation().migrateSession()
.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
.invalidSessionUrl("/expired")
.maximumSessions(1)
.maxSessionsPreventsLogin(true)
.sessionRegistry(sessionRegistry());

带有

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

然而,由于某些原因,让两个不同的浏览器在同一用户登录的情况下进行API调用,这是不起作用的。有什么建议吗?

当部署了多个副本(实例(和会话的oauth应用程序存储在redis等中时,SessionRegistryImpl是不够的,请使用SpringSessionBackedSessionRegistry,它允许在集群环境中与Spring Security进行并发会话管理。

https://docs.spring.io/spring-session/docs/current/api/org/springframework/session/security/SpringSessionBackedSessionRegistry.html

@Inject
@Named("redisConnectionFactory")
private RedisConnectionFactory redisConnectionFactory;
@SuppressWarnings({ "unchecked" })
@Bean
public SessionRegistry sessionRegistry()
{
return new SpringSessionBackedSessionRegistry(new RedisIndexedSessionRepository(sessionRedisOperations()));

}

@Bean
public RedisOperations<Object, Object> sessionRedisOperations()
{
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Override
public void configure(HttpSecurity http) throws Exception
{
http
.sessionManagement()
.maximumSessions(maximumSessions)
.expiredUrl(("/login?ex=MultiSession"))
.sessionRegistry(sessionRegistry())
....
}
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1800, redisFlushMode = RedisFlushMode.IMMEDIATE)
public class RedisConfig
{

@Bean
public RedisConnectionFactory redisConnectionFactory()
{
LettuceClientConfiguration clientConfig = getLettuceClientConfiguration();

....
}
}

最新更新