I have a Spring Boot backend application, and an AngularJS front-end application; they run on application servers on different ports (front end on port 3000, backend on port 8443). Because of this, the spring boot application needed to support CORS.
OLD
I originally had the application set up with Global CORS configuration, similar to the following. All REST endpoints, HTTP GET/PUT/POST supported, with localhost port 3000 as the allowed Origin.
public class CherryShoeApplication {
public static void main(String[] args) {
SpringApplication.run(CherryShoeApplication.class, args);
}
/*
* Since spring boot 1.3, Global CORS configuration can be defined by registering
* a WebMvcConfigurer bean with a customized addCorsMappings(CorsRegistry) method
*/
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("GET", "PUT", "POST")
.allowedOrigins("http://localhost:3000")
;
}
};
}
}
Needed to update the WebSecurityConfig to allow all HTTP OPTIONS through. Spring Security pre-authorization was used to protect the application, in this particular example.
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.addFilterBefore(ssoFilter(),
RequestHeaderAuthenticationFilter.class)
.authenticationProvider(preauthAuthProvider()).csrf().disable()
.authorizeRequests()
.antMatchers(HttpMethod.OPTIONS, "/**").permitAll() // allow CORS OPTIONS calls through
.anyRequest().authenticated();
}
}
NEW
I wanted to move Global CORS configuration out of the Java Config and into application.properties, so it'd be easier to update without a code update.
The same Java Config above (public WebMvcConfigurer corsConfigurer()) is now configured as the following in application.properties:
# ENDPOINTS CORS CONFIGURATION (EndpointCorsProperties)
# Set whether credentials are supported. When not set, credentials are not supported.
endpoints.cors.allow-credentials=false
# Comma-separated list of headers to allow in a request. '*' allows all headers.
endpoints.cors.allowed-headers=*
# Comma-separated list of methods to allow. '*' allows all methods.
endpoints.cors.allowed-methods=GET,PUT,POST
# Comma-separated list of origins to allow. '*' allows all origins. When not set, CORS support is disabled.
endpoints.cors.allowed-origins=http://localhost:3000
# Comma-separated list of extra headers to include in a response, these get exposed by default
# Cache-Control, Content-Language, Content-Type, Expires, Last-Modified, Pragma
#endpoints.cors.exposed-headers=
# How long, in seconds, the response from a pre-flight request can be cached by clients.
#endpoints.cors.max-age=1800
Key takeaway:
There was no way to do a global cors configuration via essentially an "empty" WebMvcConfigurer corsConfigurer (In other words, completely removing the WebMvcConfigurer corsConfigurer @Bean/method), and then use only the application.properties to configure it. To get the application.properties cors parameters recognized, the @CrossOrigin annotation also needs to be added to each controller. I decided to create a base class and have each controller extend it, so it'd be easier to maintain in the future.
/**
* Base class so all controllers can extend this class to inherit the @CrossOrigin annotation
*/
@CrossOrigin
public class CrossOriginController {
// empty, just need the CrossOrigin annotation
}
If you know of any other way to do a global cors configuration using application.propeties cors parameters, please let me know!
You did point out one item that I found interesting: I hadn't found anything that said that the @CrossOrigin notation was required for the application.properties to take effect. I did notice that I could just add the notation, with nothing in the properties file and everything worked. And, if I didn't use the notation, and only used the properties file, the user did receive CORS errors.
ReplyDeleterefer here: http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html
ReplyDeletespringboot support 2 properties for CORS support:
endpoints.cors.allowed-origins=http://example.com
endpoints.cors.allowed-methods=GET,POST
Key point for this article was:
DeleteThere was no way to do a global cors configuration via essentially an "empty" WebMvcConfigurer corsConfigurer, and then use the application.properties to configure it. To get the application.properties cors parameters recognized, the @CrossOrigin annotation needs to be added to each controller. I decided to create a base class and have each controller extend it, so it'd be easier to maintain in the fugure.