Home > Software design >  How to disable CORS only for dev profile in the application-dev.yml file?
How to disable CORS only for dev profile in the application-dev.yml file?

Time:12-16

I'm trying to disable CORS, because I'm getting the following error:

Access to fetch at 'https://localhost:9000/api/foo' from origin 'https://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. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. Failed to load resource: net::ERR_FAILED

I want CORS only disabled when the dev profile is active. How can I achieve this?

I've already tried the following:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

Update: There is another class that I think is related to this problem:

@EnableWebSecurity
public class WebSecurityConf extends WebSecurityConfigurerAdapter {
    @Bean
    CorsConfigurationSource corsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList(
                "https://example1.com:9000",
                "https://example2.com:9000",
        config.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);
        return source;
    }
}

CodePudding user response:

Just annotate your config with @Profile("dev"):

@Configuration
@EnableWebMvc
@Profile("dev")
public class DevWebSecurityConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                .allowCredentials(true)
                .maxAge(3600);
    }
}

Test:

class DevWebSecurityConfigTestConfigurationTest {

    private static final ApplicationContextRunner runner = new ApplicationContextRunner()
            .withConfiguration(AutoConfigurations.of(DevWebSecurityConfig));

    @Test
    void devProfileSet_devWebSecurityConfigActive() {
     runner.withPropertyValues("spring.profiles.active=dev")
             .run(context -> assertThat(context).hasSingleBean(DevWebSecurityConfig.class));
    }

    @ParameterizedTest
    @ValueSource(strings = {"default", "prod"})
    void devProfileNotSet_devWebSecurityConfigNotActive(final String profile) {
     runner.withPropertyValues("spring.profiles.active="   profile)
             .run(context -> assertThat(context).doesNotHaveBean(DevWebSecurityConfig.class));
    }
}

Update You added a CorsConfigurationSource bean to your example code. For this approach, you could declare two beans depending on the profile:

    @Profile("!dev")
    @Bean
    CorsConfigurationSource defaultCorsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList(
                "https://example1.com:9000",
                "https://example2.com:9000");
        config.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);
        return source;
    }


    @Profile("dev")
    @Bean
    CorsConfigurationSource devCorsConfigurationSource() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowedOrigins(Arrays.asList("https://localhost.com:3000");
        config.setAllowCredentials(true);
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/api/**", config);
        return source;
    }

The example test can be adapted in the way that you can also use the bean name (devCorsConfigurationSource, defaultCorsConfigurationSource) for asserting whether a bean is present or not.

You should however stick to one way: either use the addCorsMappings of the WebMvcConfigurer to configure it or with the CorsConfigurationSource bean and the .cors(withDefaults()) setting on the HttpSecurity.

  • Related