Describe the bug I'm using X509 login and trying to implement SessionCreationPolicy.ALWAYS for the /testMVCController/** endpoint and SessionCreationPolicy.STATELESS for rest of endpoints (/**). But it looks like the stateless configured for /** applies to all endpoints, despite of @Order annotation, because I'm logging the principal authorities in UserDetailsService, and even after the first login, this list of authorities is logged at each request to the server (/testMVCController/**, .js files, .css files, ...). This means that for each request the UserDetailsService is consulted, despite of SessionCreationPolicy.ALWAYS configured for /testMVCController/** endpoints.

To Reproduce Implement multiple HTTPSecurity configurations - one antMatcher (/testMVCController/**) and other for (/**). The /testMVCController/** should have SessionCreationPolicy.ALWAYS and /** should have SessionCreationPolicy.STATELESS.

Expected behavior When accessing to /testMVCController/displayUsers the user logs in once through X509 client certificate and the log I have implemented in UserDetailsService logs the authorities associated to that user. After that, all the requests to /testMVCController/displayUsers or other URL under /testMVCController/** will not go to UserDetailsService and log the authorities again because the session creation policy is always and the user is already logged in.

Sample

https://github.com/hugoalexandremf/SecurityConfiguration_SessionCreationPolicy/blob/main/SecurityConfiguration.java)

Could you please tell me if it is possible to achieve this behavior? I've searched this issue and I found various links (e.g. https://stackoverflow.com/questions/43523648/spring-session-creation-policy-per-request, https://stackoverflow.com/questions/63262262/spring-session-how-to-create-separate-session-management-policies-for-different and https://docs.spring.io/spring-security/site/docs/4.0.4.RELEASE/reference/html/jc.html#multiple-httpsecurity but none of them worked.

Comment From: sjohnr

@hugoalexandremf thanks for getting in touch. Using multiple security filter chains seems to be the correct way to achieve this. Unfortunately, I cannot reproduce your issue and your provided sample does not compile for me. Are you using a browser that is automatically passing the JSESSIONID up to the server on subsequent requests?

For reference, here's what I tried:

@EnableWebSecurity
public class SecurityConfiguration {

    @Bean
    @Order(1)
    public SecurityFilterChain customSecurityFilterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .antMatcher("/test/**")
            .authorizeRequests((authorizeRequests) -> authorizeRequests
                .anyRequest().authenticated()
            )
            .sessionManagement(sessionManagement -> sessionManagement
                .sessionCreationPolicy(SessionCreationPolicy.ALWAYS)
            )
            .httpBasic(Customizer.withDefaults());
        // @formatter:on

        return http.build();
    }

    @Bean
    @Order(2)
    public SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception {
        // @formatter:off
        http
            .antMatcher("/**")
            .authorizeRequests((authorizeRequests) -> authorizeRequests
                .anyRequest().authenticated()
            )
            .sessionManagement(sessionManagement -> sessionManagement
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            )
            .httpBasic(Customizer.withDefaults());
        // @formatter:on

        return http.build();
    }

    @Bean
    public UserDetailsService userDetailsService() {
        UserDetails userDetails = User.builder()
            .username("user")
            .password("password")
            .roles("USER")
            .build();

        UserDetailsService delegate = new InMemoryUserDetailsManager(userDetails);
        return (username) -> {
            System.out.println("In UserDetailsService");
            return delegate.loadUserByUsername(username);
        };
    }

}

Comment From: hugoalexandremf

Thank you very much for your answer @sjohnr.

I was missing some details on my configuration. I was catching all the requests to /testMVCController/** and that was working, but in addition to catch the requests to any endpoint of the type /testMVCController/** (e.g.: /testMVCController/usersList), I also have to catch the requests that these pages make to get their scripts (.js files, .css files, .png files). What was happening was: the request to /testMVCController/usersList), was configured with SessionCreationPolicy.ALWAYS, but the subsequent requests such as usersList.js, usersList.css, etc were configured with SessionCreationPolicy.STATELESS, and in these cases the X509CustomUserDetailsService was always consulted.

Example: GET request to /testMVCController/usersList works, but there also requests in this usersList page to usersList.js, usersList.css, etc.

So, once I included these resource paths in the antMatchers all worked perfectly.

Once again, I apologize for opening this since it was an error on my configuration. And thank you very much for the prompt response.