How to fix role in Spring Security?
Your first matcher anyRequest()
is always applied, because the order of matchers is important, see HttpSecurity#authorizeRequests
:
Note that the matchers are considered in order. Therefore, the following is invalid because the first matcher matches every request and will never get to the second mapping:
http.authorizeRequests().antMatchers("/**").hasRole("USER").antMatchers("/admin/**") .hasRole("ADMIN")
Your modified and simplified configuration:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/users/all").hasRole("admin")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.exceptionHandling().accessDeniedPage("/403");
}
The problem is with the ordering of your rules when you configure your HttpSecurity
. What's happening is when the request comes in and hits the
authorizeRequests().anyRequest().authenticated()
and since the user is authenticated it never makes it to the
.antMatchers("/users/all").hasRole("admin")
Here is an example of how you can configure it:
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.httpBasic()
.and()
.authorizeRequests()
.antMatchers("/public").permitAll()
.antMatchers("/user").hasRole("USER")
.antMatchers("/admin").hasRole("ADMIN")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.exceptionHandling().accessDeniedPage("/403");
}
It uses the chain of responsibility pattern. It will go through the chain of rules until it finds a rule that matches. Any rules that come after the rule that matches are never reached. Generally when writing the rules for authenticated requests, the more specific rule will come first.