You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot 3多用户登录Session覆盖问题求助

问题解决:Spring Boot 3多用户登录Session覆盖问题

问题原因

你的配置中虽定义了SessionRegistry和SessionAuthenticationStrategy,但未将其与Spring Security核心流程关联,导致会话无法被正确跟踪管理;同时默认会话控制策略未适配多用户独立会话的需求。

修改后的配置代码

package com.springboot.Admin_Officer_Security_Temp.Config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.session.SessionRegistryImpl;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.session.ConcurrentSessionControlAuthenticationStrategy;
import org.springframework.security.web.authentication.session.SessionAuthenticationStrategy;
import org.springframework.security.web.session.HttpSessionEventPublisher;
import com.springboot.Admin_Officer_Security_Temp.Service.UserDetailsServiceImpl;

@Configuration
@EnableWebSecurity
public class UserConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        return new UserDetailsServiceImpl();
    }

    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setUserDetailsService(userDetailsService());
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        return authenticationProvider;
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorize -> authorize
                        .requestMatchers("/css/**", "/images/**", "/login").permitAll()
                        .requestMatchers("/Myprofile", "/Updateprofile", "/Adduser", "/Allusers", "/Dashboard").authenticated()
                        .anyRequest().authenticated())
                .formLogin(form -> form
                        .loginPage("/login")
                        .permitAll()
                        .defaultSuccessUrl("/Dashboard")
                        .failureUrl("/login?error=true")
                        .authenticationStrategy(sessionAuthenticationStrategy()))
                .logout(logout -> logout
                        .invalidateHttpSession(true)
                        .deleteCookies("JSESSIONID")
                        .logoutSuccessUrl("/login"))
                .sessionManagement(session -> session
                        .sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
                        .sessionRegistry(sessionRegistry())
                        .maximumSessions(-1)
                        .maxSessionsPreventsLogin(false));
        return http.build();
    }

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

    @Bean
    public SessionAuthenticationStrategy sessionAuthenticationStrategy() {
        ConcurrentSessionControlAuthenticationStrategy strategy = new ConcurrentSessionControlAuthenticationStrategy(sessionRegistry());
        strategy.setMaximumSessions(-1); // 允许同一用户创建无限独立会话
        return strategy;
    }

    @Bean
    public HttpSessionEventPublisher httpSessionEventPublisher() {
        return new HttpSessionEventPublisher();
    }
}

关键修改点

  • 关联认证策略:在formLogin中添加.authenticationStrategy(sessionAuthenticationStrategy()),确保登录流程使用自定义会话控制逻辑。
  • 注册SessionRegistry:在sessionManagement中配置.sessionRegistry(sessionRegistry()),让Spring Security能跟踪所有活跃会话。
  • 配置并发会话规则:
    • maximumSessions(-1):设为-1允许同一用户创建无限独立会话,若需限制并发数可改为具体数值(如2)。
    • maxSessionsPreventsLogin(false):达到最大会话数时允许新登录,旧会话保持有效;若设为true,则超过限制时新登录会被拒绝。
  • 完善会话策略Bean:在sessionAuthenticationStrategy()中显式设置最大会话数,确保策略生效。

测试注意事项

测试多用户登录时需使用不同浏览器或隐身窗口,同一浏览器会共享Cookie导致JSESSIONID被覆盖,出现看似会话被替换的情况,这是浏览器正常行为,而非代码问题。

内容的提问来源于stack exchange,提问作者No Op

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 21:54:57