Enable Cross Origin Resource Sharing (CORS) for Spring REST Api

 

 

What is CORS (Cross Origin Resource Sharing)?

Cross Origin Resource Sharing is something that is declared by the w3c on communication between different domains. By CORS, communications between the same domain will be allowed to users and the communications that are cross-originated will be restricted to a few techniques. We can see this when we are talking to APIs mostly. The REST call may give us an error. This is because the server and the client sides are on different domains and the communication between them are restricted by CORS rules.

If you want to learn more,please do a google search. you can find a lot of resources related to CORS and their importance. 

The Spring has given a nice explanation and that can accessed with following URL.

https://spring.io/understanding/CORS

 

Importance of CORS

The importance of the CORS implementation comes with the security aspects. It blocks the calls made by unknown domains and keeps the paths open only to the known domains. So the security is ensured despite the attacking requests.

 

It works well with POSTman and Other REST Clients. but not with my code ?

This is the common complain made by most of the developers. The common complain about CORS is that the REST calls work in the REST clients but they doesn’t work in the real application and gives an error. REST clients like Postman, Advanced REST Client doesn’t raise this error because they send some additional header information to bypass the issue. So our applications have to be configured to bypass the CORS restrictions when communicating.

 

What are the headers related to CORS?

Header names starting with ‘Access-Control-’ are the ones related to CORS.

 

Implementation of CORS.

This is the most awaiting part of the article. There are different ways to implement the CORS (Cross Origin Resource Sharing) in your Spring REST Api. You can select one of them depending on your application requirement and nature.

  • Enable CORS in Controller method(s) – @CrossOrigin annotation
  • Enable CORS globally for the application (With Spring Security)

You do not have to implement  all the above approaches for your application for configuring CORS. Just implement the most suitable approach depending on your application. we will look at each of them in detailed.

 

1. Enable CORS in Controller method(s)

This can be achieved by adding @CrossOrigin annotation to the Controller (or RestController) methods.

 @CrossOrigin(origins = "http://localhost:9000")
 @GetMapping("/greeting")
 public Greeting greeting(@RequestParam(required=false, defaultValue="World") String name) {
    return new Greeting(counter.incrementAndGet(), String.format(template, name));
 }

 

This @CrossOrigin annotation enables cross-origin requests only for this specific method.

By default, its allows all origins, all headers, the HTTP methods specified in the @RequestMapping annotation and a maxAge of 30 minutes is used.

You can customize this behavior by specifying the value of one of the annotation attributes: originsmethodsallowedHeadersexposedHeadersallowCredentials or   maxAge. In this example, we only allow http://localhost:9000 to send cross-origin requests.

It is also possible to add this annotation at controller class level as well, in order to enable CORS on all handler methods of this class.

 

This approach is useful if you want to maintain a customized way of allowing the access  for each controller endpoints from the requests from different clients  (different originated servers/domains).

e.g:-

  • method1 can be accessed by only from the requests from domain abc
  • method2 should be restricted from the requests from domain abc.
  • method3 can be accessed by any request from any domain.

So in this case, we need to have a way of configuring CORS based on the controller methods.

 

 

2. Enable CORS globally for the application with Spring Security

Declare the following bean in your Spring Security Configuration file.

@Bean
CorsConfigurationSource corsConfigurationSource() 
{
    CorsConfiguration configuration = new CorsConfiguration();
    configuration.setAllowedOrigins(Arrays.asList("*"));
    configuration.setAllowedMethods(Arrays.asList("GET", "POST", "OPTIONS", "DELETE", "PUT", "PATCH"));
    configuration.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
    configuration.setAllowCredentials(true);
    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
    source.registerCorsConfiguration("/**", configuration);
    return source;
}

 

configuration.setAllowCredentials(true); should  be added since you are using Spring Security here.

 

Wait……  It is not over. we need to configure the Spring Security CORS Configuration.

 

If you are using Spring  Security, then you need to enable the CORS support in the Spring Security configuration as follows.

http.cors();

 

This is to handle the pre-flight CORS request properly before reaching the Spring Security Authentication filters.

Spring Framework provides first class support for CORS. CORS must be processed before Spring Security because the pre-flight request will not contain any cookies (i.e. the JSESSIONID or any Authentication headers). If the request does not contain any cookies (or any authentication headers) and Spring Security is first, the request will determine the user is not authenticated (since there are no cookies in the request) and reject it. In order to avoid such misbehavior, we need to enable the CORS support in Spring security. Then the pre-flight request will be handled properly (before reaching to the Spring Security Authentication Filters).

 

What is CORS pre-flight request?

A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood.

It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method, Access-Control-Request-Headers, and the Origin header.

A preflight request is automatically issued by a browser, when needed. In normal cases, front-end developers don’t need to craft such requests themselves.

 

References:

https://spring.io/guides/gs/rest-service-cors/

https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request

https://docs.spring.io/spring-security/site/docs/current/reference/html/cors.html

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s