【问题标题】:Spring Cross Origin Resource Sharing : Preflight response is not successfulSpring Cross Origin Resource Sharing:预检响应不成功
【发布时间】:2020-11-09 23:20:15
【问题描述】:

我在 StackOverflow 上看到了很多关于这个主题的其他问题,但没有解决我的问题。

我在localhost 端口8000 上使用SpringBoot 开发了一个rest API。我正在尝试从浏览器的fetch API 向端点发出请求。我还使用以下 bean 启用了 CORS:

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/**")
                    .allowedOrigins("*")
                    .allowedHeaders("GET", "POST", "PUT", "DELETE")
                    .allowCredentials(true)
                    .allowedHeaders("*");
            }
        };
    }

这是我的安全配置:

@EnableWebSecurity
@Component
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Autowired private UserService userService;

    public SecurityConfiguration() {
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .csrf().disable()
        .authorizeRequests()
        .antMatchers("/api/register", "/h2-console/**").permitAll()
        .antMatchers("/**").authenticated()
        .and().httpBasic();

        http.headers().frameOptions().sameOrigin();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth
        .userDetailsService(userService)
        .passwordEncoder(passwordEncoder());
    }

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

我仍然收到以下错误,而不是所有这些设置:

Preflight response is not successful
Fetch API cannot load http://localhost:8000/api/register/ due to access control checks.
Failed to load resource: Preflight response is not successful

【问题讨论】:

    标签: java spring spring-security cors fetch


    【解决方案1】:

    嗯,我最近尝试了很多配置,都是在网上找到的:) 我的情况略有不同,我将 Kotlin 与 Spring Boot 和 WebFlux 一起使用,但我认为总的来说它也应该与 Java 一起使用。

    我发现你必须在 SecurityWebFilterChain 中指定 cors 配置。其他配置(包括官方 Spring Security 文档)不起作用。

    @EnableWebFluxSecurity
    @EnableReactiveMethodSecurity
    class WebSecurityConfig {
        @Bean
        fun configure(http: ServerHttpSecurity): SecurityWebFilterChain? {
            val config = CorsConfiguration().applyPermitDefaultValues()
    
            config.maxAge = 8000L
            config.allowCredentials = true
            config.allowedOrigins = listOf("http://localhost:4200")
            config.allowedHeaders = listOf("*")
            config.allowedMethods =
                listOf(HttpMethod.OPTIONS.name, HttpMethod.GET.name, HttpMethod.DELETE.name, HttpMethod.PUT.name)
            config.exposedHeaders = listOf(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)
    
            val source = UrlBasedCorsConfigurationSource().apply {
                registerCorsConfiguration("/**", config)
            }
    
            http
                .cors {
                    it.configurationSource(source)
                }
                .authorizeExchange {
                    it.pathMatchers("/auth").permitAll()
                    it.anyExchange().authenticated()
                }
                .oauth2ResourceServer {
                    it.jwt()
                }
    
            return http.build()
        }
    }
    

    【讨论】:

      【解决方案2】:

      查看https://www.baeldung.com/spring-security-cors-preflight

      使用 Spring Security 时,除非明确提及,否则所有没有有效身份验证令牌的请求都会被阻止。浏览器正在使用options 方法发送请求。根据我的配置,该请求将被阻止。因此,要从安全性中排除 cors,我们需要启用它。

      @Override
      protected void configure(HttpSecurity http) throws Exception {
          http
          .cors().and()
          ...//
      }
      

      【讨论】:

        【解决方案3】:
        protected void configure(HttpSecurity http) throws Exception {
            http.cors().configurationSource(request -> {
                        CorsConfiguration cors = new CorsConfiguration();
                        cors.setAllowedOrigins(
                                Lists.newArrayList("*"));
                        cors.setAllowedMethods(Lists.newArrayList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
                        cors.setAllowedHeaders(Lists.newArrayList("*"));
                        return cors;
                    })
        }
        

        【讨论】:

          【解决方案4】:

          尝试将此添加到您的SecurityConfiguration

          @Bean
              public CorsConfigurationSource corsConfigurationSource() {
                  final CorsConfiguration configuration = new CorsConfiguration();
                  configuration.setAllowedOrigins(Arrays.asList("*"));
                  configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE"));
                  configuration.setAllowCredentials(true);
                  configuration.setAllowedHeaders(Arrays.asList("*"));
                  configuration.setExposedHeaders(Arrays.asList("x-auth-token", "xsrf-token"));
                  final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                  source.registerCorsConfiguration("/**", configuration);
                  return source;
              }
          

          【讨论】:

          • 感谢您的回答。但是,它仍然给出相同的响应
          猜你喜欢
          • 2016-02-17
          • 2017-03-14
          • 2021-07-02
          • 2020-09-05
          • 1970-01-01
          • 2016-11-10
          • 1970-01-01
          • 2021-09-03
          • 2017-02-02
          相关资源
          最近更新 更多