"After all, the engineers only needed to refuse to fix anything, and modern industry would grind to a halt." -Michael Lewis

Enable Massive Growth

How to Selectively Allow Cross Origin Resource Sharing in Spring Boot

May 2019

A single page application (SPA) architecture usually involves an end user getting a smattering of javascript files when he/she makes a request to a URL endpoint. After the javascript files load and start executing code, they usually make AJAX calls to interact with the back end from that point onwards. This pairs nicely with a microservice architecture based on REST over HTTP, since the front end SPA can effectively act as a client to any microservice that it needs information from.

Cross Origin Resource Sharing is a mechanism that browsers enforce to try and prevent an AJAX call being made to a server that is not properly configured to receive it. This is a strict mechanism: if the browser isn't using the exact URI resource and port number to request the resource, then the browser enforces this policy.

Let's say you have a website, spa.nickolasfisher.com, and users of your site get their smattering of javascript files and small html file when they request your home page. Then you want to make a backend request to api.nickolasfisher.com, since that's the gateway for the microservices you need to interact with. Well, if it's a GET request, then the browser will let you send the request directly, but will require a response header like:

Access-Control-Allow-Origin: https://spa.nickolasfisher.com

If it doesn't see that (it also supports wildcards, so it doesn't have to be that exactly), then the response will not make it into the sandbox. Further, if you try to make any request to the backend that is not a GET request (e.g. POST, PUT, etc.), the browser will send a "preflight" request to the backend via the OPTIONS method that wants a collection of headers like:

  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
  • Access-Control-Max-Age

It will make this request to the same endpoint that your browser wants to talk to, so while you could fairly easily do this manually, it definitely sniffs of DRY in a very real way.

Thankfully, Spring Boot provides a very easy mechanism to set a cross origin policy that can be defined in one place. In this example, I set up a CORS mapping to allow all requests for a default Angular application that gets served at localhost:4200:

@Configuration
@Profile("dev")
public class AppConfig {

  @Bean
  public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurer() {
      @Override
      public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**").allowedOrigins("http://localhost:4200");
      }
    };
  }
}

For more information, take a look at the current spring documentation on CORS support.

Nick Fisher is a software engineer in the Pacific Northwest. He focuses on building highly scalable and maintainable backend systems.