Spring Boot CORS Configuration Example

The CORS (Cross-Origin Resource Sharing) allows a webpage to request additional resources into the browser from other domains such as API data using AJAX, font files, style sheets etc. We need CORS because modern browsers usually have the same-origin security policy (browsers prohibit AJAX calls to resources outside the current origin).

In this Spring boot tutorial, we will learn to enable CORS support in Spring MVC applications at the method level and the global level.

See Also: Creating a CORS Filter using javax.servlet.Filter

1. How to Apply CORS Configuration?

Spring MVC handler mapping mechanism provides the built-in support for CORS. Spring checks the CORS config before executing the mapped handler method. If the Origin header is present and differs from the host of the request, we must have explicitly declared CORS configuration.

There are typically two ways to apply the CORS on a Spring application:

  • Using @CrossOrigin annotation at @Controller class and method level. It allows controlling the CORS configuration at the “method level”.
  • Overriding CorsRegistry on WebMvcConfigurer bean. It allows to define the CORS configuration at the “global level” and applies to methods from multiple controllers using the path patterns.

2. Method Level CORS Configuration with @CrossOrigin

2.1. @CrossOrigin Annotation

Spring MVC provides @CrossOrigin annotation that marks the annotated method or type as permitting cross-origin requests.

@CrossOrigin
@GetMapping("/{id}")
public Record retrieve(@PathVariable Long id) { ... }

The annotation supports following attributes:

  • origins: list of allowed origins. Its value is placed in the Access-Control-Allow-Origin header of both pre-flight and actual responses. The“*” or undefined (default) means that all origins are allowed.
  • allowedHeaders: list of request headers that can be used during the actual request. Its value is used in the preflight’s Access-Control-Allow-Headers response header. The “*” or undefined (default) means that all headers requested by the client are allowed.
  • methods: list of supported HTTP request methods. If undefined (default), methods defined by @RequestMapping are used.
  • exposedHeaders: list of response headers that the browser will allow the client to access. By default, it is an empty list.
  • allowCredentials: determines whether browser should include any cookies associated with the request. By default, credentials are allowed.
  • maxAge: refers to maximum age (in seconds) of the cache duration for pre-flight response’s Access-Control-Max-Age header. Default is 1800 seconds or 30 minutes.

By default, @CrossOrigin allows:

  • all origins
  • all headers
  • all HTTP methods specified in the @RequestMapping annotation
  • maxAge of 30 minutes

2.2. @CrossOrigin on Controller Class

When applied on the @Controller class top, CORS configuration is applied to each handler method in that class. In following example, CORS configuration is applicable on both handler methods.

@CrossOrigin(origins = "*", allowedHeaders = "*")
@RestController("/records")
public class HomeController
{
  @GetMapping("/{id}")  
  public Record retrieve(@PathVariable Long id) { ... }

  @PostMapping("/")  
  public ResponseEntity create(@RequestBody Record record) { ... }
}

2.3. Overriding CORS Configuration

We can apply the CORS config at class level and well as method level as well. When applied in both places, configuration at method level takes priority.

@CrossOrigin(origins = "*", allowedHeaders = "*")
@RestController("/records")
public class HomeController
{
  @GetMapping("/{id}")  
  @CrossOrigin(origins = "*")
  public Record retrieve(@PathVariable Long id) { ... }
}

3. Global CORS Configuration

To avoid repeating the same configuration over each handler method, we can configure some of the CORS configuration at global level and then set URL-based CorsConfiguration mappings individually on any handler method.

By default, global configuration enables the following:

  • All origins.
  • All headers.
  • GETHEAD, and POST methods.
  • maxAge set to 30 minutes.

3.1. Using CorsRegistry Callback

To enable CORS for the whole application, use WebMvcConfigurer to add CorsRegistry.

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

  @Override
  public void addCorsMappings(CorsRegistry registry) {

    registry.addMapping("/api/**")
      .allowedOrigins("https://example.com")
      .allowedMethods("GET", "POST")
      .allowedHeaders("header1", "header2", "header3")
      .exposedHeaders("header1", "header2")
      .allowCredentials(true).maxAge(3600);

    // Add more mappings...
  }
}

3.2. Using WebMvcConfigurer Bean

In Spring boot application, it is recommended to just declare a WebMvcConfigurer bean.

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

4. CORS with Spring Security

To enable CORS support through Spring security, configure CorsConfigurationSource bean and use HttpSecurity.cors() configuration.

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

	@Override
	protected void configure(HttpSecurity http) throws Exception {
		http.cors().and()
			//other config
	}

	@Bean
	CorsConfigurationSource corsConfigurationSource()
	{
		CorsConfiguration configuration = new CorsConfiguration();
		configuration.setAllowedOrigins(Arrays.asList("https://example.com"));
		configuration.setAllowedMethods(Arrays.asList("GET","POST"));
		UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		source.registerCorsConfiguration("/**", configuration);
		return source;
	}
}

Drop me your questions in comments section.

Happy Learning !!

Sourcecode on Github

13 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

Comments are closed for this article!

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.