0

I am trying to implement SpringSecurity mechanism on this little project, that will limit interactions with the URL of the request by roles.

I have two roles USER and ADMIN, USER can see the items, but not add or delete them, while ADMIN can do both.

Now the problem, the requests from USER role and even unauthenticated users to create/delete/read an item are allowed somehow. It seems to me that my application is not configured correctly somewhere.

SecurityConfig:

@EnableWebSecurity @EnableGlobalMethodSecurity(prePostEnabled = true) @Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception { auth.inMemoryAuthentication() .withUser("user").password("{noop}12345").roles("USER").and() .withUser("admin").password("{noop}12345").roles("ADMIN"); } @Override protected void configure(HttpSecurity http) throws Exception { http.httpBasic().and().authorizeRequests() .antMatchers("api/**").hasRole("ADMIN") .antMatchers("api/items", "api/items/").hasRole("USER") .anyRequest().authenticated() .and().csrf().disable().headers().frameOptions().disable(); } } 

Controller:

@RestController public class ItemController { @Autowired private ItemService itemService; @GetMapping("/api/items") public List<Item> getItems() { return itemService.getAllItems(); } @PostMapping(value = "/api/addItem",consumes = {"application/json"},produces = {"application/json"}) @ResponseBody public Item addItem(@RequestBody Item item) { itemService.addItem(item); return item; } @DeleteMapping(value = "api/deleteItem/{id}") @ResponseBody public String deleteItem(@PathVariable int id) { itemService.deleteItem(id); return "Deleted"; } } 

I am sending requests to the following URL's:

http://localhost:8080/api/items // GET http://localhost:8080/api/addItem // POST http://localhost:8080/api/deleteItem/4 // DELETE 
0

2 Answers 2

3

Have you tried adding slashes to your antmatcher patterns, such as:

antMatchers("/api/**").hasRole("ADMIN") 

The Spring documentation mentions:

Note: a pattern and a path must both be absolute or must both be relative in order for the two to match. Therefore it is recommended that users of this implementation to sanitize patterns in order to prefix them with "/" as it makes sense in the context in which they're used.

Furthermore, Spring security uses the first match of all the matching rules expressed. I would recommend reordering the matchers from most-specific to less-specific as otherwise a call to api/items will be matched by the api/** matcher instead of being matched by the api/items matcher.

.antMatchers("/api/items", "api/items/").hasRole("USER") .antMatchers("/api/**").hasRole("ADMIN") 
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your advice, I have tried antMatchers("/api/items", "api/items/", "/api/items/", "api/items").hasRole("USER") .antMatchers("/api/**").hasRole("ADMIN"), which unfortunately didn't help, if I use noauth method in Postman it will allow its execution
@dur please correct me if I am wrong, shouldn't this line allow only authenticated requests.anyRequest().authenticated()?
@Hatik: Yes, if you use .anyRequest().authenticated() all URLs have to be authenticated.
@dur I finally managed to understand the problem which allowed users with no authentication to access some level of functionality. Postman saves cookies from the last request, that is why they appeared authenticated. Maybe the whole problem also because of that, will try it out
1

On top of @GetMapping or @PostMapping you can add following annotation to manage Role based access

@PreAuthorize("hasAnyRole('ROLE_ADMIN')") @PostMapping(value = "/api/addItem",consumes = {"application/json"},produces = {"application/json"}) @ResponseBody public Item addItem(@RequestBody Item item) { itemService.addItem(item); return item; } 

1 Comment

it gives me 403 Forbidden response, when I am almost sure my credentials are ok, and sometimes after restarting the app 401 Unauthorized...

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.