-
Notifications
You must be signed in to change notification settings - Fork 40.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Broken CORS Support with Spring Security #5834
Comments
This feels to me like it should be handled in Spring Security as it would be generally useful to everyone using Spring Security, not just using Spring Boot and Spring Security. What you you think, @rwinch? |
If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed. |
Ping @rwinch |
Which feedback do you need from me? |
@rudolfschmidt Sorry for the confusion. It's @rwinch that we need some feedback from |
@rudolfschmidt Thanks for the report. I don't know that there is a lot that can be done with the current CORS APIs. Spring Security has no insight as to what the CORS configuration Spring MVC is providing, so it cannot leverage that information to inject the headers. At the only way I see this working is using the Filter as you have already described. Perhaps @rstoyanchev or @sdeleuze have some ideas though. |
If there is no way around, I would suggest to remove these Annotations if Spring Technologies dont support it sufficient. In every web app you need a kind of authentication. What is the benefit of those annotations if you cant use them with spring security and you need to develop your own filter system. Even if you dont need spring security you still need your own implementation of an authentication system that will not work with those annotations I guess. |
If you want to define CORS configuration in a single place and get it used by both Spring MVC and Spring Security, the filter based solution is indeed a good one. In that case, don't use UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://domain1.com);
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
Filter corsFilter = new CorsFilter(source); In order to get this filter taken in account, you can use it with Spring Security @Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
} That said, for your use case there is maybe an improvement we discussed with @dsyer: supporting |
We are also looking for ways to expose the knowledge that we have with In the meantime however as Sebastien pointed out, we do provide a |
I'm going to close this one. It sounds like some improvements in Spring Framework will be available in due course and there's nothing to be done in Spring Boot to address this. |
I have updated my Spring + CORS blog post to add more details about the filter based solution: https://spring.io/blog/2015/06/08/cors-support-in-spring-framework#filter-based-cors-support and also answered on Stackoverflow. I will update it again if we achieve better integration between Spring MVC and Spring Security as suggested by @rstoyanchev. |
@rudolfschmidt I wanted to let you know that Spring Security 4.1.1 was released with what should be a fix for the CORS issues you were having. Take a look at the second example which leverages the CORS configuration from Spring MVC http://docs.spring.io/spring-security/site/docs/4.1.x/reference/htmlsingle/#cors NOTE: You must use Spring Framework 4.3.1 to take advantage of this feature because it is the first release to provide the necessary hooks. |
Cors headers were not set when there was no security context (401) or authorizatin issue (403). This was a pb because Chrome didn't call fetch.then(xxx), but instead fetch.catch(xxx) and we didn't have access to statusCode in catch. See : * spring-projects/spring-boot#5834 * JakeChampion/fetch#201
I have tried the suggestion in the blog post, but I am getting a redirect in the OPTIONS request and hence the GET fails. Can you please take a look? |
I had to set spring.filter-order: 50 (some high number), so that corsFilter appears before springSecurityFilterChain and OAuth2ClientContextFilter. Then it works. Is this the right fix ? Is bean.setOrder(0) not taking effect or getting overridden by some other springSecurity code? |
Hello @vramku5 |
Hi @nebrass, I tried it, and it doesn't seem to take precedence. Maybe the explicit set by spring code overrides annotations.
The output from spring-boot:run. You can see that the cors filter is after spring security filter chain. If I uncomment the line which has bean.setOrder, then corsfilter gets mapped before.
|
Since Spring Security 4.1, this is the proper way to make Spring Security support CORS (also needed in Spring Boot 1.4/1.5):
and:
Do not do any of below, which are the wrong way to attempt solving the problem:
Reference: http://docs.spring.io/spring-security/site/docs/4.2.x/reference/html/cors.html |
@ceefour Thanks man, your solutions works for me. |
@bretoiurazvan there's no problem with that. the "do not do" is only for |
@ceefour - That configuration above is still not working for OPTIONS preflight requests, as I'm still seeing the referenced error;
and:
|
Using Spring Boot in combination with Spring Security and enabling Cors Support with Annotation @crossorigin leads to a broken cors response if the authentication with spring security fails.
Considering java script code for cors request:
The output needs to be 200. If the credentials are valid, the request will be 200.
Considering the usecase the credentials are wrong, you would expect output 401 (the standard code for failed authentication). but with spring boot and spring security the output will be 0 with the browser notification:
XMLHttpRequest cannot load http://localhost:5000/api/token. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://rudolfschmidt:3000' is therefore not allowed access. The response had HTTP status code 401.
The OPTION request goes through
and the reserver response
and the result is
everthing is fine.
but now the real request starts:
and the response is
the result is
its also fine, but because the failing header Access-Control-Allow-Origin the ajax request is broken.
I assume that spring security doesnt notice that corsSupport is enabled, because the CrossOrigin Annotiation is at the RestController. Spring Security handles like a gateway before the request has a chance to reach the Annotation that enables the Cors Headers.
The solution is adding a CorsFilter in the Spring Security Chan.
My Spring Code
The solution works but the external filter is ugly and should be work out of the box.
I hope spring boot is the right repository for that issue cause it refers to spring security as well.
The text was updated successfully, but these errors were encountered: