Spring Security: all endpoints return status 200 and unresponsive to constraints as antMatchers

Viewed 395

I want to restrict usage of endpoints based on roles: admin/user.

So I'm trying to implement Spring Security using NoOpPasswordEncoder (for testing purpose), but the problem is:
all endpoints return status 200 and unresponsive to constraints as antMatchers.

To clarify: I want to log in as user and get the error because of antMatcher:

.antMatchers("/api/addresses")
.hasAuthority("ROLE_ADMIN")

but I'm getting 200 using current configuration now.

I've tested Spring Security configuration in format:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(inMemoryUserDetailsManager());
    }

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        final Properties users = new Properties();
        users.put("admin","{noop}admin,ROLE_ADMIN,enabled");
        users.put("user","{noop}user,ROLE_USER,enabled");
        return new InMemoryUserDetailsManager(users);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/addresses")
                .access("hasAuthority('ROLE_ADMIN')")
                .antMatchers("/api/address/**")
                .access("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

based on example config.

While investigating, I've tried to comment, e.g. lines:

.antMatchers("/api/address/**")
.access("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")

to check what happens and still receive 200 when log in as user.

also I've tried to use hasAuthority() methods like:

@Configuration
@EnableWebSecurity
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(inMemoryUserDetailsManager());
    }

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        final Properties users = new Properties();
        users.put("ADMIN","{noop}admin,ROLE_ADMIN,enabled");
        users.put("USER","{noop}user,ROLE_USER,enabled");
        return new InMemoryUserDetailsManager(users);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .antMatchers("/api/addresses")
                .hasAuthority("ROLE_ADMIN")
                .antMatchers("/api/address/**")
                .hasAnyAuthority("ROLE_ADMIN", "ROLE_USER")
                .anyRequest()
                .authenticated()
                .and()
                .httpBasic()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

following the correct order with antMatchers(), when more specific rules have to go first, but it still doesn't help me.

Does anyone know what I'm missing here? Thanks in advance for any ideas.

UPD #1:

I've tried to clear cookies in Postman, log in as user, but I'm still getting 200.

enter image description here

I'm getting 401 only if I don't use Basic Auth in Postman for GET request:

enter image description here

UPD #2:

I've reproduced this issue using versions of technologies:

  • Java 11
  • spring-boot-starter-parent 2.5.3
  • spring-boot-starter-security 2.5.3
1 Answers

Cause & solutions:


The cause of issue was redundant configuration option:

server.servlet.context-path=/api

because /api prefix was already present in .antMatchers()


Solution #1:

To fix it I've removed it from application.properties file and add this prefix directly to endpoints.


Solution #2: It can be solved vice versa: remove prefix /api in antMatchers() and leave:

server.servlet.context-path=/api

using application.properties


Solution #3:

Also I've solved the problem using another configuration:

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(inMemoryUserDetailsManager());
    }

    @Bean
    public InMemoryUserDetailsManager inMemoryUserDetailsManager() {
        final Properties users = new Properties();
        users.put("admin","{noop}admin,ROLE_ADMIN,enabled");
        users.put("user","{noop}user,ROLE_USER,enabled");
        return new InMemoryUserDetailsManager(users);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
                .authorizeRequests()
                .anyRequest()
                .permitAll()
                .and()
                .httpBasic()
                .and()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }
}

with adding annotations on methods of controller:

@PreAuthorize("hasAuthority('ROLE_ADMIN')") 

and accordingly:

@PreAuthorize("hasAuthority('ROLE_ADMIN') or hasAuthority('ROLE_USER')")

As result I'm getting 403 instead of 200:

enter image description here

Related