允许CORS与Spring Security 6.1.1和经过身份验证的请求

ycl3bljg  于 2023-08-04  发布在  Spring
关注(0)|答案(2)|浏览(290)

我已经从Sping Boot 2.5升级到3.1,它附带了Spring Security 6.1.1。对登录身份验证REST服务的调用工作正常,但对其他REST控制器的所有需要身份验证令牌的请求都被CORS策略阻止。
我已经按照Springs文档中的说明禁用了CORS,但它不起作用。https://docs.spring.io/spring-security/reference/reactive/integrations/cors.html#page-title
以下是我的当前配置:

@Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.addAllowedOriginPattern("*");
        configuration.setAllowedMethods(Arrays.asList("GET","POST","PUT","PATCH","DELETE","OPTIONS"));
        configuration.setAllowCredentials(false);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors(cors -> cors.configurationSource(corsConfigurationSource()))
                //.cors(cors -> cors.disable()) <<--- does not work as documented
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(request -> request
                    .requestMatchers("/api/auth/**").permitAll()
                    .requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN")
                    .requestMatchers("/api/v1/**").authenticated()
            )
            .sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
            .authenticationProvider(authenticationProvider())
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }

字符串
我试过使用.cors(cors -> cors.disable())设置禁用CORS,但它没有禁用CORS过滤。

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors(cors -> cors.disable()) 
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(request -> request
                    .requestMatchers("/api/auth/**").permitAll()
                    .requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN")
                    .requestMatchers("/api/v1/**").authenticated()
            )
            .sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
            .authenticationProvider(authenticationProvider())
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        return http.build();
    }


还尝试将@CrossOrigin注解标记添加到REST控制器类,但没有任何效果。还验证了我有带有@EnableWebSecurity annotation的@Configuration annotation(Spring Security中的另一个更改)。
我错过了什么?

33qvvth1

33qvvth11#

我能让它工作的唯一方法是在SecurityFilterChain中禁用CORS,并用@CrossOrigin注解RestController。如果您配置了CorsConfigurationSource,则@CrossOrigin annotations将被忽略(或至少没有效果),并且它根本不适用于Spring Security 6.1。
下面是工作配置:

@Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .cors(AbstractHttpConfigurer::disable)
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(request -> request
                    .requestMatchers("/api/auth").permitAll()
                    .requestMatchers(HttpMethod.OPTIONS).permitAll()
                    .requestMatchers(SYS_ADMIN_PATTERNS).hasAuthority("SYSTEM_ADMIN")
                    .requestMatchers("/api/v1/**").authenticated()
            )
            .sessionManagement(manager -> manager.sessionCreationPolicy(STATELESS))
            .authenticationProvider(authenticationProvider())
            .addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
        ;
        SecurityFilterChain chain = http.build();
        log.info("Configured security filter chain: {}",chain);
        return chain;
    }

字符串
然后确保在类级别或单个方法级别的REST控制器上有@CrossOrigin注解。

@RestController
@RequestMapping("/api/auth")
@RequiredArgsConstructor
@CrossOrigin
public class AuthenticationController {
...
}

axr492tv

axr492tv2#

经过几天的努力,我得出了一些结论,比如这是如何工作的。
我在飞行前请求中遇到了401错误
我遵循文档代码,因为preflight请求导致了问题,我添加了一个专门用于preflight请求的requestMather

.requestMatchers(HttpMethod.OPTIONS,"/**").permitAll()

字符串
x1c 0d1x的数据
并在类级别将@CrossOrigin添加到控制器

相关问题