'Spring CORS No 'Access-Control-Allow-Origin' header is present
I am getting the following problem after porting web.xml to java config
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.
Based on a few Spring references, the following attempt has been tried:
@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
@Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
.allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
"Access-Control-Request-Headers")
.exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
.allowCredentials(true).maxAge(3600);
}
}
The values chosen were taken from a working web.xml filter:
<filter>
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
<param-name>cors.allowed.origins</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.methods</param-name>
<param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
<param-name>cors.allowed.headers</param-name>
<param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
<param-name>cors.exposed.headers</param-name>
<param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
<param-name>cors.support.credentials</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>cors.preflight.maxage</param-name>
<param-value>10</param-value>
</init-param> </filter> <filter-mapping>
<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
Any ideas why the Spring java config approach is not working like the web.xml file did?
Solution 1:[1]
Helpful tip - if you're using Spring data rest you need a different approach.
@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.getCorsRegistry().addMapping("/**")
.allowedOrigins("http://localhost:9000");
}
}
Solution 2:[2]
We had the same issue and we resolved it using Spring's XML configuration as below:
Add this in your context xml file
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="*"
allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
allowed-methods="GET, PUT, POST, DELETE"/>
</mvc:cors>
Solution 3:[3]
Omkar's answer is quite comprehensive.
But some part of the Global config part has changed.
According to the spring boot 2.0.2.RELEASE reference
As of version 4.2, Spring MVC supports CORS. Using controller method CORS configuration with @CrossOrigin annotations in your Spring Boot application does not require any specific configuration. Global CORS configuration can be defined by registering a WebMvcConfigurer bean with a customized addCorsMappings(CorsRegistry) method, as shown in the following example:
@Configuration
public class MyConfiguration {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**");
}
};
}
}
Most answer in this post using WebMvcConfigurerAdapter, however
The type WebMvcConfigurerAdapter is deprecated
Since Spring 5 you just need to implement the interface WebMvcConfigurer:
public class MvcConfig implements WebMvcConfigurer {This is because Java 8 introduced default methods on interfaces which cover the functionality of the WebMvcConfigurerAdapter class
Solution 4:[4]
Following on Omar's answer, I created a new class file in my REST API project called WebConfig.java with this configuration:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("*");
}
}
This allows any origin to access the API and applies it to all controllers in the Spring project.
Solution 5:[5]
If you are using Spring Security ver >= 4.2 you can use Spring Security's native support instead of including Apache's:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
The example above was copied from a Spring blog post in which you also can find information about how to configure CORS on a controller, specific controller methods, etc. Moreover, there is also XML configuration examples as well as Spring Boot integration.
Solution 6:[6]
as @Geoffrey pointed out, with spring security, you need a different approach as described here: Spring Boot Security CORS
Solution 7:[7]
public class TrackingSystemApplication {
public static void main(String[] args) {
SpringApplication.run(TrackingSystemApplication.class, args);
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:4200").allowedMethods("PUT", "DELETE",
"GET", "POST");
}
};
}
}
Solution 8:[8]
If you want to allow all origins(*) then use setAllowedOriginPatterns instead of setAllowedOrigins
Could you please follow the below link
https://github.com/spring-projects/spring-framework/issues/26111
Solution 9:[9]
I also had messages like No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.
I had configured cors properly, but what was missing in webflux in RouterFuncion was accept and contenttype headers APPLICATION_JSON like in this piece of code:
@Bean
RouterFunction<ServerResponse> routes() {
return route(POST("/create")
.and(accept(APPLICATION_JSON))
.and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}
Solution 10:[10]
For some reason, if still somebody not able to bypass CORS, write the header which browser wants to access your request.
Add this bean inside your configuration file.
@Bean
public WebSecurityConfigurerAdapter webSecurity() {
return new WebSecurityConfigurerAdapter() {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.headers().addHeaderWriter(
new StaticHeadersWriter("Access-Control-Allow-Origin", "*"));
}
};
}
This way we can tell the browser we are allowing cross-origin from all origin. if you want to restrict from specific path then change the "*" to {'http://localhost:3000',""}.
Helpfull reference to understand this behaviour https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example
Solution 11:[11]
This is how I fix Access-Control-Allow-Origin is present" problem after lots of hit and try and research.
After adding Spring security lots of developers face cross origin problem, this is the fix of that problem.
adding the definition of the custom filter class
public class CsrfTokenLogger implements Filter { private Logger logger = Logger.getLogger(CsrfTokenLogger.class.getName()); @Override public void doFilter( ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { Object o = request.getAttribute("_csrf"); CsrfToken token = (CsrfToken) o; filterChain.doFilter(request, response); } }Adding the custom filter in the configuration class
@Configuration public class ProjectConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.addFilterAfter( new CsrfTokenLogger(), CsrfFilter.class) .authorizeRequests() .antMatchers("/login*").permitAll() .anyRequest().authenticated(); } }
Solution 12:[12]
I solved this same problem in this way. Basically adding this @EnableWebSecurity annotation and adding protected void configure(HttpSecurity http) throws Exception {}
Change from this:
@Configuration
public class WebConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}
};
}
}
to this
@Configuration
@EnableWebSecurity
public class WebConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.antMatcher("/**").authorizeRequests().antMatchers("/**").permitAll().anyRequest().authenticated();
http.cors().and().csrf().disable();
}
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}
};
}
}
Solution 13:[13]
I have found the solution in spring boot by using @CrossOrigin annotation.
@Configuration
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Solution 14:[14]
reversebind was correct in his answer that Spring Data Rest does indeed have a different approach. However I couldn't get the code sample they provided to work as I couldn't import RepositoryRestConfigurerAdapter. After digging through the documentation, I instead used this class which worked for me.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.rest.core.config.RepositoryRestConfiguration;
import org.springframework.data.rest.webmvc.config.RepositoryRestConfigurer;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
@Configuration
class CustomRestMvcConfiguration {
@Bean
public RepositoryRestConfigurer repositoryRestConfigurer() {
return new RepositoryRestConfigurer() {
@Override
public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config, CorsRegistry cors) {
cors.addMapping("/**")
.allowedOrigins("http://localhost:4200");
}
};
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
