如何解决Spring Security中的角色?

Abd*_*ELL 1 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");
}
Run Code Online (Sandbox Code Playgroud)

这是问题所在:

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

我认为这个查询中的问题:

"select username, password, 1 from users where username=?" 
Run Code Online (Sandbox Code Playgroud)

据说那username是主键?

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

dur*_*dur 7

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

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

http.authorizeRequests().antMatchers("/**").hasRole("USER").antMatchers("/admin/**")
            .hasRole("ADMIN")
Run Code Online (Sandbox Code Playgroud)

您修改和简化的配置:

@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");
}
Run Code Online (Sandbox Code Playgroud)


Jas*_*ite 6

问题在于配置HttpSecurity. 发生的事情是当请求进来并击中

authorizeRequests().anyRequest().authenticated() 
Run Code Online (Sandbox Code Playgroud)

并且由于用户已通过身份验证,因此它永远不会进入

.antMatchers("/users/all").hasRole("admin")
Run Code Online (Sandbox Code Playgroud)

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

@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");
}
Run Code Online (Sandbox Code Playgroud)

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