Search code examples
spring-bootspring-mvcspring-securitycors

No 'Access-Control-Allow-Origin' header is present on the requested resource in Spring Boot 3


This is my CORSConfig class

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class CORSConfig{

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("*")
                        .allowedMethods("HEAD", "GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS")
                        .allowedHeaders("*")
                        .allowCredentials(false)
                        .maxAge(3600);
            }
        };
    }
}

This Bean I have define in SecurityConfig.java

@Bean
public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
    http.csrf(csrf -> csrf.disable())
            .cors(httpSecurityCorsConfigurer ->
                    httpSecurityCorsConfigurer.configurationSource(request ->
                                    new CorsConfiguration().applyPermitDefaultValues()))
            .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
            .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth ->
                    auth.requestMatchers("/api/auth/**").permitAll()
                            .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
                            .requestMatchers("/api/test/**").permitAll()
                            .anyRequest().authenticated()
            );

    http.authenticationProvider(authenticationProvider());

    http.addFilterBefore(authenticationJwtTokenFilter(), UsernamePasswordAuthenticationFilter.class);

    return http.build();
}

I am using spring boot 3.1.6, spring-security 6.1.5 with JDK 17. Above configuration I have used to handle CORS. This is working fine when I test the API from Postman and Swagger on server.

But when I intergrate react.js in frontend then GET, POST methods are working fine but for PUT method this is giving No 'Access-Control-Allow-Origin' header is present on the requested resource error.

I have try the answers of old question regarding this on stackoverflow and also try with Google. Also coordinate with my teammates but no success.


Solution

  • You are using applyPermitDefaultValues, so only the defaults are set, see CorsConfiguration:

    applyPermitDefaultValues

    public CorsConfiguration applyPermitDefaultValues()

    By default CorsConfiguration does not permit any cross-origin requests and must be configured explicitly. Use this method to switch to defaults that permit all cross-origin requests for GET, HEAD, and POST, but not overriding any values that have already been set. The following defaults are applied for values that are not set:

    • 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).

    You have to configure your custom CorsConfiguration accordingly.

    See also CORS.