skip to Main Content

I came across an Issue where public urls won’t work in Spring security, when you already have an SessionID which is not valid anymore.

Example:
I have the user-register page and gave it a permitAll access like so:

http.authorizeRequests().antMatchers("/register**").permitAll();
http.authorizeRequests().anyRequest().authenticated();
http.formLogin().loginPage("/login").permitAll();

For my Session settings i have:

http.sessionManagement().invalidSessionUrl("/login?logoutcause=sessiontimeout");
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED);
http.sessionManagement().sessionAuthenticationErrorUrl("/login");
http.sessionManagement().maximumSessions(1).maxSessionsPreventsLogin(true);
http.sessionManagement().sessionFixation().newSession();

If i have a sessionID from a previous session, which is maybe an old and invalid one, and i hit the Route “/register”, spring complains about the invalid session ID and redirects me to “/login”.
Just to mention it: Everything else, like login, ressource management, protected urls and logout is working as expected with the configuration.

Reproducing this: Use Redis-Session management in Spring. Got to login page, flush redis db with console. Access the register page directly in browser -> redirected to login because of invalid session id.

o.s.s.w.s.SessionManagementFilter        : Requested session ID 8ad2e166-bc21-4646-8390-ad8d1043baec is invalid.
w.s.SimpleRedirectInvalidSessionStrategy : Starting new session (if required) and redirecting to '/login?logoutcause=sessiontimeout'
o.s.s.w.DefaultRedirectStrategy          : Redirecting to '/login?logoutcause=sessiontimeout'

Why does Spring even check the session id for a route that have “public” access?

The next Step:
if i fully disable any security checks on the route itself, sadly the required ressources like js and css assets trigger the same behavior and either i get redirected to login, or the assets simply do not get delivered (both no option 😀 )

@Override
public void configure(WebSecurity web) throws Exception {
  web.ignoring().antMatchers("/register/**");
  super.configure(web);
}

My Solution and Workaround

I disabled the following config which solved all my problems

// DISABLED
// http.sessionManagement().invalidSessionUrl("/login?logoutcause=sessiontimeout"); 

My Question

This can not be the best way to do it, right?
What is the better and more secure way to do it.
Please help me to understand why this is done this way by spring, or what i configured the wrong way.

2

Answers


  1. I have solved the same issue by adding the following config:

    .antMatchers("/login-invalid").permitAll()
    
    Login or Signup to reply.
  2. I had same issue, and solved like below.

    0. pre-requisite

    • jdk 17
    • spring-boot 2.7

    1. create custom InvalidSessionStrategy

    @Component
    public class MyInvalidSessionStrategy implements InvalidSessionStrategy {
    
      private final InvalidSessionStrategy simpleRedirectStrategy;
    
      private final InvalidSessionStrategy requestedUrlRedirectStrategy;
    
      private final HandlerMappingIntrospector handlerMappingIntrospector;
    
      public MyInvalidSessionStrategy(HandlerMappingIntrospector handlerMappingIntrospector) {
        this.simpleRedirectInvalidSessionStrategy = new SimpleRedirectInvalidSessionStrategy("/login?logoutcause=sessiontimeout");
        this.requestedUrlRedirectStrategy = new RequestedUrlRedirectInvalidSessionStrategy();
        this.handlerMappingIntrospector = handlerMappingIntrospector;
      }
    
      @Override
      public void onInvalidSessionDetected(HttpServletRequest request, HttpServletResponse response)
          throws IOException {
    
        var matcher = new MvcRequestMatcher(handlerMappingIntrospector, "/register/**");
    
        if (matcher.matches(request))) {      
          requestedUrlRedirectStrategy.onInvalidSessionDetected(request, response);
        } else {
          simpleRedirectStrategy.onInvalidSessionDetected(request, response);
        }
      }
    }
    

    2. configure spring-securiry and register custom InvalidSessionStrategy

    @Configuration
    @EnableWebSecurity
    public class WebSecurityConfig {
    
      @Bean
      SecurityFilterChain filterChain(
          HttpSecurity http,
          MyInvalidSessionStrategy invalidSessionStrategy)
          throws Exception {
    
        return http
          .login(...)
          .logout(...)
          .sessionManagement(
            configurer -> configurer
              .invalidSessionStrategy(invalidSessionStrategy))
          .build();
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search