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
.