spring-projects / spring-projects/spring-security

Websocket XHR fallbacks get IllegalStateException: Cannot create a session after the response has been committed upgrading to Boot 3.2.7

Open
#14,864 7 comments 0 reactions 1 assignee View on GitHub

@jzheaux is already working on this.

Since Apr 16, 2024.

in: saml2 status: feedback-provided
Dominant language
Java
Stars
9.6k
Forks
6.3k
Avg merge
2d 11h
Merged PRs (30d)
52

Description

Describe the bug
I recently upgraded from Boot 2.7 to 3.2.7.
Since then I am getting a lot of java.lang.IllegalStateException: Cannot create a session after the response has been committed
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:99)`

2024-04-08T10:39:14.519+02:00 E o.a.c.c.C.[.[.[.[dispatcherServlet] - Servlet.service() for servlet [dispatcherServlet] threw exception
java.lang.IllegalStateException: Cannot create a session after the response has been committed`

It seems to be related to Websocket requests that fallback to XHR:
[08/Apr/2024:10:39:14 +0200] "POST /ws/684/0jl1hqqe/xhr_streaming?t=1712565509691 HTTP/1.1" 500 83 "***" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36" 50009522

I am using requireExplicitSave = false for the context and SessionCreationPolicy.ALWAYS

SecurityConfig:

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http,
                                           RelyingPartyRegistrationResolver rpResolver,
                                           SkolfedSamlResponseAuthenticationConverter authConverter) throws Exception {
        // Begin SAML
        var authenticationRequestResolver = new OpenSaml4AuthenticationRequestResolver(rpResolver);
        authenticationRequestResolver.setRequestMatcher(new AntPathRequestMatcher("/saml/login"));
        var authenticationProvider = new OpenSaml4AuthenticationProvider();
        authenticationProvider.setResponseAuthenticationConverter(authConverter);
        http.saml2Login(samlLogin ->
                samlLogin
                        .loginPage(DISCOVERY_URL)
                        .successHandler(samlSuccessRedirectHandler())
                        .failureHandler(new SamlAuthenticationFailureHandler())
                        .authenticationManager(new ProviderManager(authenticationProvider))
                        .authenticationRequestResolver(authenticationRequestResolver)
                        .authenticationConverter(new Saml2AuthenticationTokenConverter(rpResolver))
                        .loginProcessingUrl("/saml/SSO"));
        // End SAML

        http.csrf(AbstractHttpConfigurer::disable);
        http.securityContext((securityContext) -> securityContext
                .securityContextRepository(new HttpSessionSecurityContextRepository())
                .requireExplicitSave(false)
        );
        http.addFilterAt(concurrencyFilter(), ConcurrentSessionFilter.class)
                .addFilterAt(nompRememberMeAuthenticationFilter(), RememberMeAuthenticationFilter.class)
                .addFilterBefore(new NompJwtAuthenticationFilter(nompJwtIssuer()), BasicAuthenticationFilter.class)
                .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.ALWAYS).sessionAuthenticationStrategy(sas()));
        return http.build();
    }

```

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.