问题
I wrote SpringBoot application with authentication via web login form. Class WebSecurityController is responsible for authentication and authorization. Here is its code:
@Controller
@EnableWebSecurity
public class WebSecurityController extends WebSecurityConfiguration {
@Autowired
DataSource dataSource;
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/users/getAll").access("hasRole('ROLE_ADMIN')")
.anyRequest().permitAll()
.and()
.formLogin().loginPage("/login")
.usernameParameter("name").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf();
}
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select name,password,enabled from users where name=?")
.authoritiesByUsernameQuery("select username, role from user_roles where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
}
It retrieves the user credentials from users and user_roles tables of the database:
mysql> select * from users;
+----+--------+---------+---------+--------------------------------------------------------------+
| id | name | salary | enabled | password |
+----+--------+---------+---------+--------------------------------------------------------------+
| 1 | Rinat | 100000 | 1 | $2a$10$Md.HmF6dVbwKLxcb09dgy.JTHKq3BLLg0ZrBHHx75fNmkH8.kGeGy |
| 2 | Juliya | 1000000 | 1 | $2a$10$XWksiqEwqJ4jWp00F37i/.A8YpknUPKi36kDd2NgwKI6EBPRRMzXa |
+----+--------+---------+---------+--------------------------------------------------------------+
mysql> select * from user_roles;
+----+----------+------------+
| id | username | role |
+----+----------+------------+
| 1 | Rinat | ROLE_ADMIN |
| 2 | Juliya | ROLE_USER |
+----+----------+------------+
Authentication works fine, but unfortunately any users can access to protected resource "/users/getAll". It seems that access("hasRole('ROLE_ADMIN')"
not working.
回答1:
i'm using springboot 2.0.4.RELEASE spring security 5.0.7.RELEASE and in my WebSecurityController i'm using the method : hasAuthority('ROLE_ADMIN')
here a fix example :
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
// old
//.antMatchers("/users/getAll").hasAuthority("ROLE_ADMIN")
//.anyRequest().permitAll()
// Update
.anyRequest().permitAll()
.antMatchers("/users/getAll").hasAuthority("ROLE_ADMIN")
.and()
.formLogin().loginPage("/login")
.usernameParameter("name").passwordParameter("password")
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403")
.and()
.csrf();
}
回答2:
Finally I repair the method configure()
and extends from WebSecurityConfigurerAdapter
as it said in Spring Security reference 6.4 Authorize Requests:
@Controller
@EnableWebSecurity
public class WebSecurityController extends WebSecurityConfigurerAdapter {
@Autowired
DataSource dataSource;
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/resources/**", "/signup", "/about").permitAll()
.antMatchers("/users/**").hasRole("ADMIN")
.antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")
.anyRequest().authenticated()
.and()
.formLogin()
.and()
.logout().logoutSuccessUrl("/login?logout")
.and()
.exceptionHandling().accessDeniedPage("/403")
;
}
@Autowired
public void configAuthentication(AuthenticationManagerBuilder auth) throws Exception {
auth.jdbcAuthentication().dataSource(dataSource)
.usersByUsernameQuery("select name,password,enabled from users where name=?")
.authoritiesByUsernameQuery("select username, role from user_roles where username=?")
.passwordEncoder(new BCryptPasswordEncoder());
}
Hope it helps somebody. Nadra, thanks!
来源:https://stackoverflow.com/questions/52825679/how-to-use-hasrole-in-spring-security