Spring Boot CORS filter - CORS preflight channel did not succeed
Solution 1
I have fixed this issue by creating a new CORS Filter:
@Component
public class CorsFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
filterChain.doFilter(request, response);
}
}
}
and added it to securty configuration:
.addFilterBefore(new CorsFilter(), ChannelProcessingFilter.class)
UPDATED - More modern way nowadays which I switched to:
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.cors()
.and()
...
}
@Bean
public CorsConfigurationSource corsConfigurationSource() {
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("*"));
configuration.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"));
configuration.setAllowedHeaders(Arrays.asList("authorization", "content-type", "x-auth-token"));
configuration.setExposedHeaders(Arrays.asList("x-auth-token"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", configuration);
return source;
}
}
Solution 2
Had the same issue getting CORS to work with spring data rest, this was the filter code I used.
/**
* Until url{https://jira.spring.io/browse/DATAREST-573} is fixed
*
* @return
*/
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
//config.setAllowCredentials(true); // you USUALLY want this
config.addAllowedOrigin("*");
config.addAllowedHeader("*");
config.addAllowedMethod("OPTIONS");
config.addAllowedMethod("HEAD");
config.addAllowedMethod("GET");
config.addAllowedMethod("PUT");
config.addAllowedMethod("POST");
config.addAllowedMethod("DELETE");
config.addAllowedMethod("PATCH");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
Solution 3
This is very simple and working well. Within the class you wrote for Web Security Configurations, enter this line httpSecury.cors();
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity httpSecurity) throws Exception {
httpSecurity.cors(); // This enables cors
// Your codes
}
}
Solution 4
I still had the CORS error after following the two tutorials:
First I followed the Web Security guide: https://spring.io/guides/gs/securing-web/#scratch
Second I followed the CORS guide: https://spring.io/guides/gs/rest-service-cors/#global-cors-configuration
To resolve my issues after following these guides I had to add http.cors()
to the http security.
@Override
protected void configure(HttpSecurity http) throws Exception {
http.cors()
.and()
...
}
Adding the .cors()
allows it to use the @Bean
I declared for my CORS configuration.
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedOrigins("http://localhost:4200");
}
};
}
Solution 5
For what its worth, the following combination solution worked for me:
1.
@Configuration
public class CorsConfiguration {
//This can be used in combination with @CrossOrigin on the controller & method.
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedMethods("HEAD","OPTIONS")
.allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept");
}
};
}
}
2. @CrossOrigin
on the RestController class. Having @CrossOrigin
reads the @RequestMapping
annotations and the HTTP methods in it. Rest of the requests are rejected with CORS error.
But you will be out of luck with the above solution if you want to use spring security in your project.
I am using spring boot version 1.5.4.RELEASE.
alexanoid
Updated on July 09, 2022Comments
-
alexanoid almost 2 years
I need to add CORS filter to my Spring Boot web application.
I have added CORS mappings as described in the following documentation http://docs.spring.io/spring/docs/current/spring-framework-reference/html/cors.html
This is my config:
@Configuration @EnableWebMvc public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { // @formatter:off registry .addMapping("/**") .allowedOrigins(CrossOrigin.DEFAULT_ORIGINS) .allowedHeaders(CrossOrigin.DEFAULT_ALLOWED_HEADERS) .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .maxAge(3600L); // @formatter:on } ... }
Right now when I'm trying to access my API I receiving a following error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://example.com/api/v1.0/user. (Reason: CORS preflight channel did not succeed).
This is a screenshot from FF console:
What am I doing wrong and how to properly configure CORS headers in order to avoid this issue ?
-
Алексей Романов about 8 yearsAt the beginning leave only required http methods in allowed methods. Then try make raw request using curl
curl -H "Origin: http://127.0.0.1" --verbose http://127.0.0.1/api/v1.0/user
. You have to see Access-Control-Allowed-* headers in response. And finally, try to specify you host (127.0.0.1 or smth. else) in AllowedOrigin. -
alexanoid about 8 yearsI have tried
allowedHeaders("xsrf-token").exposedHeaders("xsrf-token")
but still doesn't working. I think I need something like this -if ("OPTIONS".equals(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); }
but I don't know how to add this logic intoCorsRegistry registry
-
Marco Tedone about 8 yearsIf you want to support proper RESTful APIs, shouldn't you add also the PUT verb in there?
-
Nadeem Jamali almost 6 yearsI used the above example code and others too, but none of them worked on the application level. Eventually, I set the CORS over controller level.
-
Maciek Kreft almost 6 yearsIt's best configuration, because it works not only for controllers but also for interceptors! Thx!
-
Davut Gürbüz over 5 yearsOur project is not MVC and your not updated solution helped.
-
Sebastiandg7 about 5 years@alexanoid Does the last option using the CorsConfigurationSource allows to dynamically load the allowed domains from, for example, a database? Use case: an admin web app where you can control the allowed domains for your application.
-
Bằng Rikimaru almost 5 yearsThis is the only configuration which can work with $http.get in AngularJs 1.6 and I found this after hours of trying with no understand about why
-
Glenn over 4 yearsYou know, I like Spring, but CORS configuration has been causing me no end of grief. Everytime I upgrade my Springboot version, CORS is broken again for my REST app. My filter isn't being picked up. It isn't at the top. Doesn't work if you included spring-data. Always something. For the last round, this helped me for my oauth token retrieval, but I still had to keep a filter to handle the
OPTIONS
pre-flight:if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { response.setStatus(HttpServletResponse.SC_OK); }
-
Henry over 4 yearsSorry but where do you place the above code in? Or do I need to create a new class filter and create the above Bean inside the new class?
-
Romell over 4 yearsThe code is placed in any class that has the
@Configuration
annotation but there are easier ways to do this with Spring Boot 2, see comments further down the page -
rineez almost 4 yearsDocumentations and forum posts everywhere was giving same procedure but none of them mentioned this requirement to call
http.cors()
inside thevoid configure(HttpSecurity http)
implementation. I'm really thankful because this fixed my problem ultimately after a long struggle. Is this actually documented somewhere? -
rineez almost 4 yearsI had to do this inside my class with
@EnableWebSecurity
annotation, that extends WebSecurityConfigurerAdapter. (I guess it will may be a direct implementation ofWebSecurityConfigurer<WebSecurity>
interface for some others) -
seedme about 2 yearsif you are using
spring-boot-starter-web
this seems the simplest way of configuring it. mind to further notate.allowedOrigins
and.allowedHeaders
in production.