spring-security 所有角色都无法访问受保护的端点[duplicate]

x7yiwoj4  于 2022-11-11  发布在  Spring
关注(0)|答案(1)|浏览(156)

此问题在此处已有答案

Springboot Security hasRole not working(3个答案)
两个月前关门了。
我正在尝试使用Spring Security保护一个端点。我创建了两个角色,ADMINCUSTOMER,出于测试目的,我正在尝试保护一个特定的端点/api/v1/customers/,以便只有ADMIN可以访问它。
结果发现没有一个角色,甚至ADMIN也无法访问它。我意识到我以前没有使用api/v1/customers,而只是使用/customers/,所以我修复了这个问题。
同样基于一个关于类似问题的答案,我已经输入了两次相同的端点,在最后有和没有斜线(检查配置代码,你会知道)。
似乎没有什么工作,我分享我的SecurityConfig和控制器(只有有用的部分)类如下。

客户控制器.java

@CrossOrigin(origins = "http://localhost:3000/")
@RestController
@RequestMapping("api/v1")
public class CustomerController {

    @Autowired
    private CustomerRepository customerRepository;

    @RequestMapping(value = "/customers", method = RequestMethod.GET)
    public List<Customer> getAllCustomers(){
        return customerRepository.findAll();
    }
}

安全配置.java

@Configuration
@EnableWebSecurity
public class SecurityConfiguration{

    @Bean
    protected SecurityFilterChain filterChain(HttpSecurity http) throws Exception{
        // disabling the csrf isn't really the best way of dealing with this, need to fix !!!
        http
            .csrf().disable();
        http
            .authorizeRequests()
                .antMatchers(HttpMethod.GET, "/api/v1/customers/", "/api/v1/customers").hasRole("ADMIN")
                .anyRequest().authenticated().
                .and()
            .formLogin();
        return http.build();
    }

    @Bean
    protected InMemoryUserDetailsManager configureAuthentication(){

        List<UserDetails> userDetails = new ArrayList<>();
        List<GrantedAuthority> customerRoles = new ArrayList<>();
        customerRoles.add(new SimpleGrantedAuthority("CUSTOMER"));
        List<GrantedAuthority> adminRoles = new ArrayList<>();
        adminRoles.add(new SimpleGrantedAuthority("ADMIN"));

        userDetails.add(new User("user_customer", this.PasswordEncoder().encode("password"), customerRoles));
        userDetails.add(new User("user_admin", this.PasswordEncoder().encode("password"), adminRoles));
        return new InMemoryUserDetailsManager(userDetails);
    }

    @Bean
    public PasswordEncoder PasswordEncoder(){
        return new BCryptPasswordEncoder(10);
    }
}
d4so4syb

d4so4syb1#

如javadoc中所述,SecurityExpressionRoot.hasRole().hasAnyRole()方法在默认情况下会将 “ROLE_" 前缀添加到传递的参数中,如果您没有更改这个默认的GrantedAuthority前缀。
因此,对于.hasRole("ADMIN"),spring-security将尝试将实际的授权名称与 “ROLE_ADMIN” 匹配,而不是仅与 “ADMIN” 匹配。
但是,内存中的用户拥有一个具有 “ADMIN” 权限的SimpleGrantedAuthority,因此,您将获得403状态。
您可以通过3种方式修复它:
1.将角色另存为SimpleGrantedAuthority("ROLE_ADMIN")SimpleGrantedAuthority("ROLE_CUSTOMER")(带前缀)
1.使用.hasAuthority()而不是.hasRole()方法-第一个方法不更改传递的参数,也不添加任何前缀。
1.覆盖如下默认前缀:

@Bean
    public GrantedAuthorityDefaults grantedAuthorityDefaults() {
        return new GrantedAuthorityDefaults(""); // <- no default prefix
    }

相关问题