【问题标题】:CORS is blocking PUT, DELETE, and POST requests but GET is workingCORS 正在阻止 PUT、DELETE 和 POST 请求,但 GET 正在工作
【发布时间】:2021-11-19 19:24:27
【问题描述】:

我很茫然。我正在尝试配置CORS,并且我已经尝试了几乎所有可以在互联网/堆栈溢出上找到的东西。

请求在 Postman 中有效,但在使用 axios 的 React 中无效。

这是我删除用户的函数(这在 Postman 中有效,但在 React 中触发时无效):

 deleteEmployeeById(id) {
    // return axios.delete(API_BASE_URL + `employees/${id}`);
    var testing = "";
    return axios
      .delete(API_BASE_URL + `employees/${id}`, {
        headers: {
          Authorization: `Bearer ${HARDCODED_JWT_TESTING}`,
        },
      })
      .then("yessssss")
      .catch((error) => {
        console.log("failed to delete  emp by id" + error);
      });
  }
}

我有一个如下所示的 SecurityConfig.java 文件:

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    MyUserDetailsService myUserDetailsService;

    @Autowired
    private JwtRequestFilter jwtRequestFilter;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        // TODO : use this line when i implement bcrypt
        // auth.userDetailsService(myUserDetailsService).passwordEncoder(passwordEncoder());
        auth.userDetailsService(myUserDetailsService);

    }

    // TODO : should use this password encoder
    // public PasswordEncoder passwordEncoder() {
    // return new BCryptPasswordEncoder();
    // }

    @Bean
    public PasswordEncoder passwordEncoder() {
        // TODO : not secure. Use a different encoder. testing only
        return NoOpPasswordEncoder.getInstance();
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // allow users to access "authenticate" page without being authenticated
        // all other requests must be authenticated
        // stateless tells it to not create a session? Do i need? Not sure yet
        // http.csrf().disable().authorizeRequests().antMatchers("/api/authenticate").permitAll().anyRequest()
        // .authenticated().and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
        http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues()).and().csrf()
                .disable().authorizeRequests().antMatchers("/api/authenticate").permitAll().anyRequest().authenticated()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);

    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        // create bean of type 'authenticationManager'
        return super.authenticationManagerBean();
    }

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setExposedHeaders(Arrays.asList("X-Auth-Token", "Authorization", "Access-Control-Allow-Origin",
                "Access-Control-Allow-Credentials"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }

}

我不知道错误在哪个函数中,但我认为它是 corsConfigurationSource() 方法。但是,我认为这不应该起作用。在我尝试为应用添加安全性之前,它曾经可以工作。

正如您在该方法中看到的那样,我已经设置了所有允许的方法,我允许所有来源等,但是在尝试从我的数据库中删除用户时仍然出现此错误:

Access to XMLHttpRequest at 'http://localhost:8080/api/employees/6151c89ea1b79f789a7a964b' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

这确实在 Postman 中工作。我可以删除用户没问题,它只是在我的前端 React 应用程序触发时不起作用。

看起来我允许CORS 中的所有内容,知道还有什么需要配置的吗??

【问题讨论】:

    标签: java spring-boot spring-security cors


    【解决方案1】:

    在实例化CorsConfiguration 后,尝试删除SecurityConfig 中的.applyPermitDefaultValues() 调用。这基本上是将 CORS 配置重置为默认值:

    • 允许所有具有 CORS 规范中定义的特殊值“*”的来源。仅当 origin 和 originPatterns 均未设置时才设置。
    • 允许“简单”方法 GET、HEAD 和 POST。
    • 允许所有标题。
    • 将最大年龄设置为 1800 秒(30 分钟)。

    另外,调用corsConfigurationSource() 方法而不是实例化一个新的CorsConfiguration

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.cors().configurationSource(corsConfigurationSource()).and().csrf()
                .disable().authorizeRequests().antMatchers("/api/authenticate").permitAll().anyRequest().authenticated()
                .and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    
        http.addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class);
    }
    

    另外,更新您的CorsConfigurationSource 如下:

    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        final CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
        configuration.setAllowedMethods(Arrays.asList("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS"));
        configuration.setAllowCredentials(true);
        configuration.setAllowedHeaders(Arrays.asList("*"));
        configuration.setExposedHeaders(Arrays.asList("X-Auth-Token", "Authorization", "Access-Control-Allow-Origin",
                "Access-Control-Allow-Credentials"));
        final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
    

    【讨论】:

      【解决方案2】:

      为了更清楚和测试的目的,您可以尝试通过以下方法测试您的corsConfigurationSource()。 请根据您的应用程序更改代码,例如来源等。

      @Bean
      CorsConfigurationSource corsConfigurationSource() {
          CorsConfiguration configuration = new CorsConfiguration();
          configuration.setAllowedOrigins(Arrays.asList("http://localhost:4200"));
          configuration.setAllowedMethods(Arrays.asList("*"));
          configuration.setAllowedHeaders(Arrays.asList("*"));
          configuration.setAllowCredentials(true);
          UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
          source.registerCorsConfiguration("/**", configuration);
          return source;
      }
      

      它基本上允许所有标头、方法和来源。它不适合生产,但出于测试目的,您可以尝试一下。

      【讨论】:

        猜你喜欢
        • 2020-08-23
        • 2022-01-11
        • 2020-01-14
        • 1970-01-01
        • 1970-01-01
        • 2015-01-17
        • 2016-09-08
        • 2018-05-05
        • 2021-08-29
        相关资源
        最近更新 更多