如何解决Spring Security中的角色?

时间:2017-03-27 17:22:10

标签: java spring spring-security

我试图在我的项目中使用Spring Security,这是代码:

@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    // TODO Auto-generated method stub
    //super.configure(auth);
    //auth.inMemoryAuthentication().withUser("admin").password("1111").roles("USER");
    auth
        .jdbcAuthentication()
            .dataSource(dataSource)
            .usersByUsernameQuery("select username, password, 1 from users where username=?")
            .authoritiesByUsernameQuery("select users_username, roles_id  from roles_users where users_username=?")
            .rolePrefix("ROLE_");
}   

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .csrf().disable();      
    http
        .httpBasic();
    http
        .authorizeRequests()
            .anyRequest().authenticated();
    http
        .authorizeRequests()
            .antMatchers("/users/all").hasRole("admin")
            .and()
        .formLogin();
    http
        .exceptionHandling().accessDeniedPage("/403");
}

问题在于:

想象一下,我们的数据库中有两个用户(一个具有user角色,另一个具有admin角色)一个管理员,第二个是用户,问题是当我连接时用户(只有user角色)可以访问管理资源(这不是预期的行为)。

我认为此查询中存在问题:

"select username, password, 1 from users where username=?" 

根据username是主键吗?

如果有人知道如何解决这个问题?

2 个答案:

答案 0 :(得分:7)

始终会应用您的第一个匹配器anyRequest(),因为匹配器的顺序非常重要,请参阅HttpSecurity#authorizeRequests

  

请注意,匹配器是按顺序考虑的。因此,以下内容无效,因为第一个匹配器匹配每个请求,并且永远不会进入第二个映射:

     
http.authorizeRequests().antMatchers("/**").hasRole("USER").antMatchers("/admin/**")
            .hasRole("ADMIN")

您修改和简化的配置:

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

答案 1 :(得分:4)

问题在于配置HttpSecurity时规则的排序。当请求进入并点击

时,会发生什么
authorizeRequests().anyRequest().authenticated() 

并且由于用户已通过身份验证,因此从未进入

.antMatchers("/users/all").hasRole("admin")

以下是如何配置它的示例:

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

它使用责任链模式。它将通过规则链直到找到匹配的规则。永远不会达到匹配规则之后的任何规则。通常,在为经过身份验证的请求编写规则时,将首先使用更具体的规则。