'Spring Boot enabling CORS by application.properties
I using Spring Boot API RESTful that get up automatically by your Entities Class. I'm consuming this apiRest from a front-end web app but it gives me this error:
No 'Access-Control-Allow-Origin' header is present on the requested resource
I'm setting the CORS configuration using the applicantion.properties specified here.
My basic configuration is:
endpoints.cors.allow-credentials=true
endpoints.cors.allowed-origins=*
endpoints.cors.allowed-methods=*
endpoints.cors.allowed-headers=*
I have tried different combinations in those variables but still not working. Any ideas?
Solution 1:[1]
This is not very clear in the official Spring documentation, and it is very easy to be misled by the official Spring Boot documentation.
The truth is that you CANNOT set the global CORS congfiguration using the application.properties file. You HAVE TO use JavaConfig as described by the Cors chapter from Spring Framework Documentation.
Just use the @EnableWebMvc annotation on a @Configuration class that implements WebMvcConfigurer and overrides the addCorsMappings method as follows:
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://domain2.com")
.allowedMethods("PUT", "DELETE")
.allowedHeaders("header1", "header2", "header3")
.exposedHeaders("header1", "header2")
.allowCredentials(false).maxAge(3600);
}
}
Solution 2:[2]
Spring boot properties prefixed by endpoints.cors.* are used by Actuator so that's why it will not work with MVC endpoints.
Solution 3:[3]
We can move actual cors related urls to application.properties anyway. It works for me with Spring Boot 5.
App.java (main class):
@SpringBootApplication
public class App extends SpringBootServletInitializer {
@Autowired
private Environment env;
public static void main(String[] args) {
SpringApplication.run(ReportsApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
String urls = env.getProperty("cors.urls");
CorsRegistration reg = registry.addMapping("/api/**");
for(String url: urls.split(",")) {
reg.allowedOrigins(url);
}
}
};
}
}
application.properties:
cors.urls=http://localhost:3000
Solution 4:[4]
You could inject the Strings, should you want to save them in the application.properties
Dev
# application-dev.properties
appName.allowedApi=http://localhost:4200
Prod
# application-prod.properties
appName.allowedApi=https://appname.com
And in your WebConfig.java
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Value("${appName.allowedApi}")
private String myAllowedApi;
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins(myAllowedApi);
}
}
Solution 5:[5]
Checked with Spring-Boot 2.1.2:
THe first thing is to know what servlet filters are already in place. Servlet filters are supposed to add response header "Access-Control-Allow-Origin". I looked up in my spring logs and decided to add CorsFilter that originally comes from Spring.
@Bean
public CorsFilter corsFilter() {
CorsConfiguration config = new CorsConfiguration();
config.addAllowedOrigin("http://127.0.0.1:4200");
config.addAllowedOrigin("http://localhost:4200");
config.addAllowedHeader("*");
config.setAllowedMethods(Arrays.asList("OPTIONS", "GET"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/actuator/**", config);
return new CorsFilter(source);
}
Since you are injecting CorsFilter - you can easily see what is happening in there. In this case - we are hitting OTHER endpoint than "/actuator/**". No configuration is available for it.
The above (null) does not mean that the "Access-Control-Allow-Origin" will not be present. It can be added by a filter other than we injected (e.g if you have controller annotated with @CrossOrigin - the cross-origin header will be added in some other mvc filter, other than our CorsFilter).
In the case below we hit /actuator:
You can also create your own custom filter that adds header to http-response. I think it is better to use standard approach, but in some debug cases it might be handy to know that by adding a line in your fileter - you can add desired.
response.addHeader("Access-Control-Allow-Origin", "*");
Note that the above contains no conditional checking offered earlier.
Hope this helps. Cheers
Solution 6:[6]
What is worth mentioning is that with newer versions of spring you can add patterns for your allowed origins using allowedOriginsPattrens builder method. In this case, you don't need to strictly provide the origins:
public class YourConfig implements WebMvConfigurer {
(...)
public void addCorsMapping(Corsregistry registry) {
registry.addMapping(""/your/endpoints/root/**)
.allowCredentials(true)
.allowedOriginsPatterns("*.your.domain1.com", "*.your.domain2.com)
.allowHeaders("*")
.allowMethods("*");
}
}
Solution 7:[7]
In application.property file add origins and headers. Make sure there are no spaces after the comma.
allowed.origins = http://localhost:3000,http://192.168.00.00:3000,http://servername:3000
allowed.headers = Content-Type,Authorization,loggedInUserId,Cache-Control,Pragma,Expires
WebMvcConfigurer implement file
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Value("${allowed.origins}")
private String allowedOrigins;
@Value("${allowed.headers}")
private String allowedHeaders;
@Override
public void addCorsMappings(CorsRegistry registry) {
CorsRegistration reg = registry.addMapping("/**").allowedMethods("*");
reg.allowedOrigins(allowedOrigins.split(","));
reg.allowedHeaders(allowedHeaders.split(","));
}
}
Solution 8:[8]
Its even simple in spring boot2 , just specify the crossdomain url in the management acutators like this
management.endpoints.web.cors.allowed-origins=http://examaple.com ,http://examaple1.com
management.endpoints.web.cors.allowed-methods=GET, POST
Solution 9:[9]
One solution for doing this for a specific controller using @CrossOrigin annotation is:
In controller class:
@CrossOrigin(origins = "${client.url}")
@Controller
@RequestMapping(path = "/foo")
public class FooController {
...
}
In application.properties:
# Client URL
client.url=http://localhost:4200
Solution 10:[10]
You may use library for configuring CORS by properties file for Mvc and Flux:
I made library special for this and implementation of this library long working in productions
for Spring-web-MVC in maven central
for Spring-web-Flux in maven central
Example
add dependency
<dependency>
<groupId>io.github.iruzhnikov</groupId>
<artifactId>spring-webmvc-cors-properties-autoconfigure</artifactId>
<version>VERSION</version>
</dependency>
add to application.yml (course you may use default application.properties)
spring:
web:
cors:
enabled: true
mappings: #spring.web.cors.mappings.<any_name>.<property>: <value>
anyName: #just any name, just for grouping properties under the same path pattern (not used in internal logic)
paths: #ant style path pattern, ATTENTION! not ordered, /** pattern override all other pattern
- /path/to/api
- /path/to/api/**
#allowed-origins: "*"
allowed-methods: GET #Enable override all defaults! If disabled: a lot more from all the controller methods included from the path pattern matches
#allowed-headers: "*"
#exposed-headers: ('*' - not-supported)
#allow-credentials: true
allowed-origin-patterns: .*
#max-age: PT30M
Solution 11:[11]
The total GC time in the log is 0.1189389 secs, which is about 118.9 ms instead of 11 seconds.
The MaxGCPauseMillis parameter in G1 is used to control the maximum pause time. The default value is 200 ms. If you want to reduce the pause time, you can consider setting MaxGCPauseMillis to the desired value.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow


