Reputation: 178
I am new to CORS headers and implementing with Spring boot. I am enabling CORS header on POST service which accept request body.
First time preflight request is made which runs fine and return 200 but when actual post request is invoked, it always return 403 forbidden with response body "Invalid CORS request".
I have read almost all spring docs and all google/stackoverflow discussions but could not find out what am I missing..huh..
In Below snippet I have tested by adding crossOrigin at top of class and top of method but no luck.
@CrossOrigin(origins = "https://domain/", allowCredentials = "false")
@RequestMapping(value = ApplicationConstants.URI_PATH)
class MainController {
@RequestMapping(value = '/postMethod', method = RequestMethod.POST)
Map<String, Object> postMethod(HttpServletResponse servletResponse,
@RequestBody(required = false) AccessToken requestedConsumerInfo) {...}
For POST method - Preflight request is invoked and result is 200 but main POST call returns 403.
Call with OPTIONS: Status code 200
Response headers (616 B)
Access-Control-Allow-Credentials true
Access-Control-Allow-Headers content-type
Access-Control-Allow-Methods POST
Access-Control-Allow-Origin https://domain
Allow GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
Cache-Control max-age=0, private, no-cache, …roxy-revalidate, no-transform
Connection close
Content-Length 0
Date Wed, 20 Dec 2017 17:57:14 GMT
Pragma no-cache
Server nginx/1.9.1
Strict-Transport-Security max-age=63072000; includeSubdomains;
Vary Origin,User-Agent
X-Frame-Options SAMEORIGIN
X-XSS-Protection 1; mode=block
Request headers (512 B)
Accept text/html,application/xhtml+xm…plication/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate, br
Accept-Language en-US,en;q=0.5
Access-Control-Request-Headers content-type
Access-Control-Request-Method POST
Connection keep-alive
Host domain
Origin https://domain
User-Agent Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/57.0
Call with POST: Status code 403
Response headers (364 B)
Cache-Control max-age=0, private, no-cache, …roxy-revalidate, no-transform
Connection close
Content-Length 20
Date Wed, 20 Dec 2017 17:57:14 GMT
Pragma no-cache
Server nginx/1.9.1
Strict-Transport-Security max-age=63072000; includeSubdomains;
Vary User-Agent
X-Frame-Options SAMEORIGIN
X-XSS-Protection 1; mode=block
Request headers (2.507 KB)
Accept application/json, text/plain, */*
Accept-Encoding gzip, deflate, br
Accept-Language en-US,en;q=0.5
Connection keep-alive
Content-Length 102
Content-Type application/json
Cookie rxVisitor=1513720811976ARCUHEC…B4SL3K63V8|6952d9a33183e7bc|1
Host domain
Origin https://domain
Referer https://domain/home/account/register
User-Agent Mozilla/5.0 (Windows NT 6.1; W…) Gecko/20100101 Firefox/57.0
Since this was not working, I have also tested by adding global configurations alone and also along with above snippet but no luck.
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurerAdapter() {
@Override
void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
registry.addMapping(ApplicationConstants.MEMBER_URL_PATH)
.allowedOrigins("https://domain/")
.allowedMethods(HttpMethod.GET.toString(),
HttpMethod.POST.toString(), HttpMethod.PUT.toString());
}
}
}
Upvotes: 1
Views: 4884
Reputation: 3347
I had the same issue, then used the annotation @CrossOrigin and it works fine, but just for GET, when I tried to make a POST I still got Cross Origin error, then this fixed for me:
Create an interceptor and added the Access Controll headers to the response. (You might not need all of them)
public class AuthInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse httpResponse, Object handler, ModelAndView modelAndView)
throws Exception {
httpResponse.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, OPTIONS, DELETE");
httpResponse.setHeader("Access-Control-Allow-Headers", "*");
httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
httpResponse.setHeader("Access-Control-Max-Age", "4800");
}
}
Then add the interceptor:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
System.out.println("++++++ WebConfig addInterceptors() ");
registry.addInterceptor(new AuthInterceptor()).addPathPatterns("/**");
}
}
I hope this save you some time, it took me a while to get this working .
Upvotes: 1
Reputation: 4507
On the preflight OPTIONS request, the server should respond with all the following (looks like you're doing this already):
Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Access-Control-Allow-Credentials (if cookies are passed)
On the actual POST request, you'll need to return at least Access-Control-Allow-Origin
and Access-Control-Allow-Credentials
. You're not currently returning them for the POST response.
Upvotes: 2