【问题标题】:How to use hasRole in Spring Security?如何在 Spring Security 中使用 hasRole?
【发布时间】:2018-10-15 22:43:57
【问题描述】:

我编写了通过 Web 登录表单进行身份验证的 SpringBoot 应用程序。 WebSecurityController 类负责身份验证和授权。 这是它的代码:

@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());
 }

}

它从数据库的 usersuser_roles 表中检索用户凭据:

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  |
+----+----------+------------+

身份验证工作正常,但不幸的是,任何用户都可以访问受保护的资源“/users/getAll”。 access("hasRole('ROLE_ADMIN')" 似乎不起作用。

【问题讨论】:

    标签: java spring security authentication authorization


    【解决方案1】:

    我正在使用 springboot 2.0.4.RELEASE spring security 5.0.7.RELEASE,在我的 WebSecurityController 中我使用的方法是:hasAuthority('ROLE_ADMIN')

    这里是一个修复示例:

    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();
     }
    

    【讨论】:

    • 我刚刚尝试了您的解决方案,不幸的是对我不起作用。有什么想法吗?
    • 问题是“AnyRequest().permitAll() 在 hasAuthority(Admin) 之后。它会覆盖访问权限我会更新代码^^ 希望它对你有用
    【解决方案2】:

    最后我修复了方法configure() 并从WebSecurityConfigurerAdapter 扩展,正如它在Spring Security 参考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());
    } 
    

    希望它可以帮助某人。纳德拉,谢谢!

    【讨论】:

      猜你喜欢
      • 2022-01-01
      • 2021-04-07
      • 2013-10-07
      • 2015-08-27
      • 2015-05-02
      • 2013-10-19
      • 2011-03-02
      • 2017-06-16
      相关资源
      最近更新 更多