CORS with spring-boot and angularjs not working
To build on other answers above, in case you have a Spring boot REST service application (not Spring MVC) with Spring security, then enabling CORS via Spring security is enough (if you use Spring MVC then using a WebMvcConfigurer
bean as mentioned by Yogen could be the way to go as Spring security will delegate to the CORS definition mentioned therein)
So you need to have a security config that does the following:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
//other http security config
http.cors().configurationSource(corsConfigurationSource());
}
//This can be customized as required
CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
List<String> allowOrigins = Arrays.asList("*");
configuration.setAllowedOrigins(allowOrigins);
configuration.setAllowedMethods(singletonList("*"));
configuration.setAllowedHeaders(singletonList("*"));
//in case authentication is enabled this flag MUST be set, otherwise CORS requests will fail
configuration.setAllowCredentials(true);
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
This link has more information on the same: https://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#cors
Note:
- Enabling CORS for all origins (*) for a prod deployed application may not always be a good idea.
- CSRF can be enabled via the Spring HttpSecurity customization without any issues
- In case you have authentication enabled in the app with Spring (via a
UserDetailsService
for example) then theconfiguration.setAllowCredentials(true);
must be added
Tested for Spring boot 2.0.0.RELEASE (i.e., Spring 5.0.4.RELEASE and Spring security 5.0.3.RELEASE)
If you want to enable CORS without using filters or without config file just add
@CrossOrigin
to the top of your controller and it work.
I had been into the similar situation. After doing research and testing, here is my findings:
With Spring Boot, the recommended way to enable global CORS is to declare within Spring MVC and combined with fine-grained
@CrossOrigin
configuration as:@Configuration public class CorsConfig { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE").allowedOrigins("*") .allowedHeaders("*"); } }; } }
Now, since you are using Spring Security, you have to enable CORS at Spring Security level as well to allow it to leverage the configuration defined at Spring MVC level as:
@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and()... } }
Here is very excellent tutorial explaining CORS support in Spring MVC framework.
UPDATE (Sep 13, 2022):
With latest version of Spring 5 and above, you have to use WebMvcConfigurer
as below:
@EnableWebMvc
public class CorsConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
}
}
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class SimpleCORSFilter implements Filter {
private final Logger log = LoggerFactory.getLogger(SimpleCORSFilter.class);
public SimpleCORSFilter() {
log.info("SimpleCORSFilter init");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me");
chain.doFilter(req, res);
}
@Override
public void init(FilterConfig filterConfig) {
}
@Override
public void destroy() {
}
}
No need extra define this filter just add this class. Spring will be scan and add it for you. SimpleCORSFilter. Here is the example: spring-enable-cors