Home > Blockchain >  Spring Boot CORS blocks DELETE requests
Spring Boot CORS blocks DELETE requests

Time:05-29

Whenever I try to send request to delete endpoint with axios, I get the following error:

Access to XMLHttpRequest at 'http://localhost:8080/api/payment_card/delete/1234123412343433' 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

Axios request is built as following :

      .delete(
        "http://localhost:8080/api/payment_card/delete/"    selectedCardId ,
        {
          headers: {
            Authorization: `Bearer ${token}`,
            "Access-Control-Allow-Origin": "**"
          },
        }
      )
      .then(function (response) {
        console.log(response);
      })
      .catch(function (error) {
        console.log(error);
      });```
My java WebSecurityConfig stays as follow:
Override protected void configure(HttpSecurity http) throws Exception {

        http = http.cors().and().csrf().disable();
        http.cors().configurationSource(request -> new CorsConfiguration().applyPermitDefaultValues());

        // Set session management to stateless
        http = http
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and();
        // Set unauthorized requests exception handler
        http = http
                .exceptionHandling()
                .authenticationEntryPoint(new AuthException())
                .and();
        http.addFilterBefore(requestFilter, UsernamePasswordAuthenticationFilter.class);
    }

And in the controller, mapping is :

    public ResponseEntity<PaymentCard> deletePaymentCard(@PathVariable Long cardNumber) {
        PaymentCard pCard = paymentCardService.deletePaymentCard(cardNumber);
        return new ResponseEntity<>(pCard, HttpStatus.OK);
    }

I tried many solutions like adding @CrossOrigin annotation, making CorsFilter but nothing seems to help at all. Ultimately, I've changed DeleteMapping to GetMapping in my controller but I feel like http policy can catch me to custody at any time :( Thanks for your time and help in advance.

CodePudding user response:

CorsConfiguration.applyPermitDefaultValues() allows not all methods as one may assume, but following methods only: GET, HEAD, POST.

To allow DELETE method, you can use following code:

http.cors().configurationSource(c -> {
    CorsConfiguration corsCfg = new CorsConfiguration();

    // All origins, or specify the origins you need
    corsCfg.addAllowedOriginPattern( "*" );

    // If you really want to allow all methods
    corsCfg.addAllowedMethod( CorsConfiguration.ALL ); 

    // If you want to allow specific methods only
    // corsCfg.addAllowedMethod( HttpMethod.GET );     
    // corsCfg.addAllowedMethod( HttpMethod.DELETE );
    // ...
});

If we configure CorsConfiguration explicitly, I recommend not to use applyPermitDefaultValues(), but specify all desired methods explicitly. Then nobody will need to remember what methods exactly are enabled by applyPermitDefaultValues(), and such code will be easier to understand.

CodePudding user response:

I could have a class that implements Filter with the following methods


@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        final HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
        response.setHeader("Access-Control-Max-Age", "3600");
        if (HttpMethod.OPTIONS.name().equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            chain.doFilter(req, res);
        }
    }

    @Override
    public void destroy() {
    }

    @Override
    public void init(FilterConfig config) throws ServletException {
    }
}


  • Related