Home > Net >  CORS is blocking PUT, DELETE, and POST requests but GET is working
CORS is blocking PUT, DELETE, and POST requests but GET is working

Time:09-28

I am at a loss. I am trying to configure CORS and I have tried just about everything I can find on the internet/Stack overflow.

Requests are working in Postman but not in React using axios.

Here is my function for deleting a user (this works in Postman but not when triggered in 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);
      });
  }
}

I have a SecurityConfig.java file that looks like this:

@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;
    }

}

I have no clue which function the error is in, but I assume it is the corsConfigurationSource() method. However, I see no issue that this shouldn't work. It used to work before I attempted to add security to the app.

AS you can see in that method, I have set all of the allowed methods, I allow all origins, ect, but I still get this error when attempting to delete a user from my database:

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.

This DOES work in Postman though. I can Delete a user no problem, it just will not work when triggered from my frontend React app.

It looks like I am allowing everything in CORS, any idea what else is left to configure??

ERRORS

CodePudding user response:

Try removing .applyPermitDefaultValues() call in SecurityConfig after instantiating CorsConfiguration. This is basically reseting CORS configuration to the defaults:

  • Allow all origins with the special value "*" defined in the CORS spec. This is set only if neither origins nor originPatterns are already set.
  • Allow "simple" methods GET, HEAD and POST.
  • Allow all headers.
  • Set max age to 1800 seconds (30 minutes).

Additionally, call corsConfigurationSource() method instead of instantiating a new 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);
}

Also, update your CorsConfigurationSource as follows:

@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;
}

CodePudding user response:

For better clarity and for the purpose of testing, can you try testing your corsConfigurationSource() by the following method. Please do change the code as it fits to your application such as origin etc.

@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;
}

It is basically allowing all headers, methods and origins. It is not ideal for production but for testing purpose you can try this. This may not solve the issue but we can start from here. Happy coding!

  • Related