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

Vaadin14升级Vaadin23后用户频繁自动登出问题排查与解决

已登录用户频繁自动登出/登录多次才成功的Vaadin问题排查与解决

问题现象

  • Vaadin14环境下,已登录用户会频繁出现自动登出情况;升级至Vaadin23后问题未解决,还新增了用户有时需多次点击登录按钮才能成功登录的现象。
  • 网站前端无报错提示,初始日志中也未发现相关异常信息。
  • 项目基于Vaadin官方启动模板搭建。

相关配置代码

SecurityConfiguration

@EnableWebSecurity
@Configuration
public class SecurityConfiguration extends VaadinWebSecurity {

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

    @Override
    protected void configure(HttpSecurity http) throws Exception {

        http.authorizeRequests().requestMatchers(new AntPathRequestMatcher("/images/*.png")).permitAll();
        http.authorizeRequests().requestMatchers(new AntPathRequestMatcher("/VAADIN/**")).permitAll();

        //http.authorizeRequests().requestMatchers(new AntPathRequestMatcher("/VAADIN/*")).permitAll();
        super.configure(http);
        setLoginView(http, LoginView2.class);
    }
    @Override
    public void configure(WebSecurity web) {
        
    }
}

CustomAuthenticationProvider

@Component
public class CustomAuthenticationProvider implements AuthenticationProvider
{
    private final Logger logger = LogManager.getLogger(CustomAuthenticationProvider.class);
    @Autowired private DatabaseController dbc;
    @Autowired
    private UserRepository _userRepository;
    @Autowired private MsGraphService _msGraphService;

    CustomAuthenticationProvider(UserRepository userRepository)
    {
        _userRepository = userRepository;
    }
    //@Autowired
    //private AuthenticationManager authenticationManager;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException
    {
        //user authentication by pw stored in DB
... 
        if(authResult)
        {
           //add authorities
            UserSessionInfo info = new UserSessionInfo(user, organisations, admins, mans, accesslists);
            UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(info, password, autorities);
            logger.info("user "+user.email+" successfully logged in");
            return token;
        }
        else
        {
            logger.info("user "+user.email+" entered the wrong password");
            throw new BadCredentialsException("Authentication failed");
        }
    }

    @Override
    public boolean supports(Class<?> aClass)
    {
        return aClass.equals(UsernamePasswordAuthenticationToken.class);
    }
}

ServiceListener(调试用)

升级至Vaadin23后,尝试通过监听Vaadin服务事件排查问题,未获取有效线索:

public class ServiceListener implements VaadinServiceInitListener
{
    private final Logger logger = LogManager.getLogger(ServiceListener.class);
    @Override
    public void serviceInit(ServiceInitEvent event) {
        logger.info("serviceInit");
        event.getSource().addSessionInitListener(
                initEvent -> logger.info("A new Session has been initialized!"));

        event.getSource().addUIInitListener(
                initEvent ->logger.info("A new UI has been initialized!"));
        event.getSource().addSessionDestroyListener(destroyed->
        {
            logger.info("session destroyed "+destroyed.getSource());
        });
    }
}

调试发现的关键日志

开启org.springframework.security调试日志后,捕获到会话相关异常:

2023-04-05 15:00:09.255 DEBUG 1 --- [https-jsse-nio-8989-exec-10] o.s.s.w.session.SessionManagementFilter  : Requested session ID 594190F39E29B84F68291BDDCA5E3DCC is invalid.
...
org.springframework.security.access.AccessDeniedException: Access is denied
...

问题根源与解决办法

根源分析

经过超100小时调试验证,确认问题是同一域名下不同端口运行了两个Vaadin站点:浏览器会为同域名的站点共用Cookie,导致两个站点不断互相覆盖Cookie中的SessionId,最终引发会话失效、权限拒绝等问题。

解决步骤

在项目的application.properties文件中,为当前站点配置独立的会话Cookie名称,避免与同域名下的其他站点冲突:

server.servlet.session.cookie.name=somewebsitecookiename

内容的提问来源于stack exchange,提问作者syn-thomas

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 22:12:52