如何配置Spring Security URL授权?

vkc1a9a2  于 2022-12-04  发布在  Spring
关注(0)|答案(1)|浏览(134)

我已将SecurityFilterChain配置为:

@EnableWebSecurity
public class WebSecurityConfig {
    ....
    
    @Bean
    public SecurityFilterChain configure(final HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .cors().disable()
            .authorizeRequests()
                .antMatchers(HttpMethod.DELETE, "/api/user/*").access("hasRole('ADMIN')")
                .antMatchers(HttpMethod.POST, "/api/user").access("hasRole('ADMIN')")
                .antMatchers("/auth/login").anonymous()
                .anyRequest().authenticated()
                .and()
            .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
            .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
}

然而,URL路径对任何经过身份验证的用户都是开放的,而不管分配的角色是什么。我已经调试了请求过滤器,以确认Principal具有正确的角色,而USER角色可以成功调用受保护的URL。
我使用的是Sping Boot 2.7.5。

gr8qqesn

gr8qqesn1#

如果您调用的路径与您声明为最后一个的授权规则(即anyRequest().authenticated())相匹配,则意味着您的测试请求与任何旨在保护URL的规则相匹配,而这些URL应仅由管理员访问,即:

.antMatchers(HttpMethod.DELETE, "/api/user/*").access("hasRole('ADMIN')")
.antMatchers(HttpMethod.POST, "/api/user").access("hasRole('ADMIN')")

***提醒:**首先声明的匹配规则始终为弱 *

因此,HTTP方法或URL不匹配(或两者都不匹配)。例如,如果您发送GET请求,这些限制将不适用。
关于URL,它应该与完全匹配,因为您使用的是antMatchers()。即,路径"/api/user"不会与该路径的其他现有别名(如"/api/user/")匹配(* 更多信息请参见here *)。
这就是为什么在Spring Security 6.0中从API中删除了antMatchers()(以及mvcMathcers()regexMatchers())并替换了requestMatchers()的原因之一。
因此,请确保HTTP-method是正确的,您调用匹配器的路径也是准确的,并考虑更新Spring依赖项,改用新的请求保护方法。
如果您没有要立即更新的平面,那么您可以使用mvcMatchers(),它使用SpringMVC匹配规则(即,它们考虑给定路径的所有现有别名),而不是antMatchers()
下面是一个如何使用Spring Security 6.0和Lambda DSL实现您的配置的示例(如果您觉得使用and()链接配置选项更方便,那么仍然支持这种DSL风格):

@Configuration
public class SecurityConfig {
    
    @Bean
    public SecurityFilterChain configure(final HttpSecurity http) throws Exception {
        return http
            .csrf(csrf -> csrf.disable())
            .cors(cors -> cors.disable())
            .authorizeHttpRequests(auth -> auth
                .requestMatchers(HttpMethod.DELETE, "/api/user/*").hasRole("ADMIN") // in Spring Security 6.0 method access() has been changed, and you don't need it anyway to verify the Role
                .requestMatchers(HttpMethod.POST, "/api/user").hasRole("ADMIN")
                .requestMatchers("/auth/login").anonymous()
                .anyRequest().authenticated()
            )
            .sessionManagement(sm -> sm.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
            .build();
    }
}

相关问题