instructions

  1. For security reasons, browsers prohibit AJAX calls to resources that reside outside the current source. For example, when you check your bank account in one TAB, you can put the Evil.com web site in another TAB. The evil.com script cannot use your credentials to make AJAX requests to your bank API (to withdraw money from your account)!
  2. Cross-raw Resource Sharing (CORS) is a W3C specification implemented by most browsers that allows you to specify in a flexible way what cross-domain requests are authorized, rather than using some less secure and less powerful hacker, such as IFrame or JSONP.
  3. Spring Framework 4.2 GA provides first-class support for out-of-the-box CORS, giving you a simpler and more powerful way to configure it than a typical filter-based solution.

Spring MVC provides advanced configuration capabilities

Controller method CORS configuration

  • You can add the @Crossorigin annotation to the @RequestMapping annotation handler method to enable CORS (by default @Crossorigin allows all the start and HTTP methods specified in the @RequestMapping annotation) :

      @RestController
      @RequestMapping("/account")
      public class AccountController {
    
          @CrossOrigin
          @GetMapping("/{id}")
          public Account retrieve(@PathVariable Long id) {
              // ...
          }
    
          @DeleteMapping("/{id}")
          public void remove(@PathVariable Long id) {
              // ...
          }
    Copy the code

    }

  • You can also enable CORS for the entire controller:

    @CrossOrigin(origins = "http://domain2.com", maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // ... } @DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... }}Copy the code

In this example, CORS support is enabled for both the Retrieve () and Remove () handler methods, and you can also see how to customize the CORS configuration using the @Crossorigin property.

You can even use both controller and method-level CORS configurations, and Spring will then combine the two annotation properties to create the combined CORS configuration.

@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin(origins = "http://domain2.com") @GetMapping("/{id}") public Account retrieve(@PathVariable Long id) { // . } @DeleteMapping("/{id}") public void remove(@PathVariable Long id) { // ... }}Copy the code

If you use Spring Security, be sure to enable CORS at the Spring Security level and allow it to take advantage of the configuration defined at the Spring MVC level.

@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and()... }}Copy the code

Global CORS configuration

In addition to fine-grained annotation-based configurations, you may also want to define some global CORS configurations. This is similar to using filters, but you can use Spring MVC declarations combined with fine-grained @Crossorigin configuration. By default, all origins and GET, HEAD, and POST methods are allowed.

JavaConfig

Enabling CORS for the entire application is similar

@Configuration @EnableWebMvc public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); }}Copy the code

If you are using Spring Boot, it is recommended to simply declare a WebMvcConfigurerbean as follows:

@Configuration public class MyConfiguration { @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); }}; }}Copy the code

You can easily change any property and only apply this CORS configuration to a specific path pattern:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/**")
        .allowedOrigins("http://domain2.com")
        .allowedMethods("PUT", "DELETE")
            .allowedHeaders("header1", "header2", "header3")
        .exposedHeaders("header1", "header2")
        .allowCredentials(false).maxAge(3600);
}
Copy the code

If you use Spring Security, be sure to enable CORS at the Spring Security level and allow it to take advantage of the configuration defined at the Spring MVC level.

XML namespace

CORS can also be configured using the MVC XML namespace.

This minimal XML configuration causes CORS on the /** path schema to have the same default properties as JavaConfig:

<mvc:cors>
    <mvc:mapping path="/**" />
</mvc:cors>
Copy the code

You can also declare several CORS mappings using custom attributes:

<mvc:cors>

    <mvc:mapping path="/api/**"
        allowed-origins="http://domain1.com, http://domain2.com"
        allowed-methods="GET, PUT"
        allowed-headers="header1, header2, header3"
        exposed-headers="header1, header2" allow-credentials="false"
        max-age="123" />

    <mvc:mapping path="/resources/**"
        allowed-origins="http://domain1.com" />

</mvc:cors>
Copy the code

If you use Spring Security, don’t forget to enable CORS at the Spring Security level:

<http> <! -- Default to Spring MVC's CORS configuration --> <cors /> ... </http>Copy the code

How does it work?

CORS requests (including pre-check with OPTIONS methods) are automatically sent to various HandlerMapping registered. They handle CORS precheck requirements and intercept CORS simple and practical requests thanks to the CorsProcessor implementation (DefaultCorsProcessor to add access-Control-Allow-Origin to the relevant CORS response headers (as by default). CorsConfiguration allows you to specify how CORS requests are handled: allowed starting points, headers, methods, and so on. It can be provided in a variety of ways:

  1. AbstractHandlerMapping#setCorsConfiguration()Allows mapping on path modeMapA fewCorsConfigurationTo specify a/api/**
  2. Subclasses canCorsConfigurationThrough rewritingAbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)Method provides its own subclasses
  3. Handlers can be implementedCorsConfigurationSourceInterface (likeResourceHttpRequestHandlerFor now) to provide for each requestCorsConfiguration.

Filter based CORS support

As an alternative to the other approaches described above, the Spring Framework also provides a CorsFilter. In this case, instead of using @crossorigin or WebMvcConfigurer#addCorsMappings(CorsRegistry), you can declare filters in your Spring Boot application, for example, as follows:

@Configuration public class MyConfiguration { @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; }}Copy the code