0

I'm developing Spring Boot and Spring Security web application with authorization and resource servers enabled. I have defined a set of users with roles assigned to them and trying to implement roles based access to REST endpoints. I was able to implement token based access to endpoints, but can't restrict access to end users, that would be based on their roles.

I have done two endpoints: /rest/products/list and /rest/products/add and trying to restrict access to /rest/products/add endpoint with the user that is of ADMIN role.

My WebSecurityConfigurerAdapter is as follows:

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

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Override
    protected void configure(final AuthenticationManagerBuilder auth) throws Exception {
        auth
            .inMemoryAuthentication()
                .passwordEncoder(passwordEncoder)
                .withUser("user1")
                    .password(passwordEncoder.encode("user1Pass"))
                    .roles("USER")
                    .and()
                .withUser("user2")
                    .password(passwordEncoder.encode("user2Pass"))
                    .roles("USER")
                    .and()
                .withUser("admin")
                    .password(passwordEncoder.encode("adminPass"))
                    .roles("ADMIN");
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {

        http
            .authorizeRequests()
                .antMatchers("/rest/products/add").hasAnyRole("ADMIN")
                .antMatchers("/rest/products/list").denyAll();
    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
}

Therefore, resource /rest/products/add should be accessible to admin / adminPass user only as far as that user has ADMIN role. But if to try to it with user1 / user1Pass, it is still accessible:

Get access token for user1 postman screen

Accessing ADMIN only related endpoint with user1 Postman screen

Also I added (in the testing purpose) in the configuration method the following rule .antMatchers("/products/list").denyAll(); Here is indicated that /products/list shouldn't be accessible to any user. But it still keeps on responding (provided access correct token).

In the similar question here How to fix role in Spring Security? the order of matchers should be from the more specific to the less. But in my case there are two matchers and no matchers that can overlap them.

I'm using Spring Boot with spring-boot-starter-security plugin version 2.5.2.

What additional configuration should be done to make .hasRole("ADMIN") and .denyAll() work as expected?

dur
  • 15,689
  • 25
  • 79
  • 125
Dmitry
  • 11
  • 4

1 Answers1

0

Finally was able to find the solution with the following:

Here there is an example of ResourceServerConfigurerAdapter class. From this and from your comment, dur, I realized that I confused ResourceServerConfigurerAdapter and WebSecurityConfigurerAdapter, trying to define access restriction matchers in WebSecurityConfigurerAdapter. I changed resource server configuration in the following way:

Method that was in WebSecurityConfigurerAdapter

 @Override
    public void configure(final HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/rest/products/add").hasAnyRole("ADMIN")
                .antMatchers("/rest/products/list").denyAll();
    }

was moved to

@Configuration
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(final HttpSecurity http) throws Exception {

        http.authorizeRequests()
                .antMatchers("/rest/products/add").hasAnyRole("ADMIN")
                .antMatchers("/rest/products/list").denyAll();
    }

}

Now restrictions defined by matchers above are working as expected.

Dmitry
  • 11
  • 4