79575443

Date: 2025-04-15 14:44:41
Score: 1.5
Natty:
Report link

I created a usable example to show that you might use @Order to match the paths.

A SecurityFilterChain with a smaller @Order number is matched before a SecurityFilterChain with a larger @Order number.

Following this pattern and matching the paths, I allowed "Admin", "Editor" and "User" to access certain paths respectively, and denied as necessary.

The config file was here.

    @Bean
    @Order(400)
    public SecurityFilterChain securityFilterChainUser(HttpSecurity http) throws Exception{
        
        String[] matchedPaths = { 
            "/user", 
            "/user/**"
        };
        
        http
            .csrf(csrf -> csrf.disable())
            .securityMatcher(
                matchedPaths
            )
            .authorizeHttpRequests(request -> 
                request
                    .requestMatchers(matchedPaths)
                    .hasAnyRole("ADMIN", "EDITOR", "USER")
                    .anyRequest()
                    .authenticated()
            )

            .sessionManagement(session -> session
                .sessionConcurrency((concurrency) -> concurrency
                                .maximumSessions(1)
                                .maxSessionsPreventsLogin(true)
                        )
            )
            .logout(logout -> logout.logoutUrl("/logout"));
            
        return http.build();
    }


    @Bean
    @Order(500)
    public SecurityFilterChain securityFilterChainUserDeny(HttpSecurity http) throws Exception{
        
        String[] matchedPaths = { 
            "/user", 
            "/user/**"
        };
        
        http
            .csrf(csrf -> csrf.disable())
            .securityMatcher(
                matchedPaths
            )
            .authorizeHttpRequests(request -> 
                request
                    .requestMatchers(matchedPaths)
                    .denyAll()
            )

            .sessionManagement(session -> session
                .sessionConcurrency((concurrency) -> concurrency
                                .maximumSessions(1)
                                .maxSessionsPreventsLogin(true)
                        )
            )
            .logout(logout -> logout.logoutUrl("/logout"));
            
        return http.build();
    }

    @Bean
    @Order(600)
    public SecurityFilterChain securityFilterChainEditor(HttpSecurity http) throws Exception{
        
        String[] matchedPaths = { 
            "/editor", 
            "/editor/**"
        };
        
        http
            .csrf(csrf -> csrf.disable())
            .securityMatcher(
                matchedPaths
            )
            .authorizeHttpRequests(request -> 
                request
                    .requestMatchers(matchedPaths)
                    .hasAnyRole("ADMIN", "EDITOR")
                    .anyRequest()
                    .authenticated()
            )

            .sessionManagement(session -> session
                .sessionConcurrency((concurrency) -> concurrency
                                .maximumSessions(1)
                                .maxSessionsPreventsLogin(true)
                        )
            )
            .logout(logout -> logout.logoutUrl("/logout"));
            
        return http.build();
    }

In my example, I used Microsoft SQL Server.

I ran the SQL statement before starting my example application.

CREATE DATABASE springboothasrole COLLATE Latin1_General_100_CS_AI_WS_SC_UTF8;

The PowerShell script to start was here.

$env:processAppDebugging="true";
$env:processAppDataSourceDriverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver";
$env:processAppDatabasePlatform="org.hibernate.dialect.SQLServer2012Dialect";
$env:processAppDataSourceUrl="jdbc:sqlserver://localhost;databaseName=springboothasrole;encrypt=false;trustServerCertificate=false;"
$env:processAppDataSourceUsername="sa";
$env:processAppDataSourcePassword="Your_Password";
./mvnw spring-boot:run;

I opened the browser and tested different paths, e.g.

http://127.0.0.1:8080
http://127.0.0.1:8080/admin
http://127.0.0.1:8080/editor
http://127.0.0.1:8080/user

The permissions were what I expected according to hasAnyRole in the example. Please see if this helps.

Reasons:
  • Contains signature (1):
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Order
  • User mentioned (0): @Order
  • Low reputation (1):
Posted by: Hdvlp