Spring 5.0.0.RC1 - CORS Support 【譯文】

3 CORS支持

3.1 介紹

出於安全考慮,瀏覽器禁止對當前源以外的資源進行AJAX調用。例如,當你在一個標籤頁檢查你的銀行帳戶時,你能夠在另外一個標籤頁打開evil.com的網站。在evil.com中的腳本不能使用你的憑據來經過AJAX請求訪問你的銀行API(例如,從你的銀行取款!)。html

跨域資源共享(Cross-origin resource sharing)(CORS)是W3C的標準大部分的瀏覽器都實現了這個標準來讓你能夠靈活地指定什麼樣的跨域請求是被受權的,而不用使用IFRAME或JSONP這些不太安全和功能不強的黑客技術。java

從Spring Framework 4.2起,CORS就支持開箱即用。CORS請求(包括一個預檢請求OPTIONS方法)自動分發到各個註冊的HandlerMapping中。因爲CorsProcessor的實現(默認是DefaultCorsProcessor),它們處理CORS預檢請求,並攔截CORS的簡單而實際請求,以便根據你提供的CORS配置添加相關的CORS響應頭(如Access-Control-Allow-Origin)。git

因爲CORS請求是自動分發的,你不須要改變DispatcherServlet dispatchOptionsRequest的初始參數值;推薦的方式是使用它的默認值(false)。github

3.2 控制器方法CORS配置

你能夠在你的@RequestMapping註解處理方法上添加一個@CrossOrigin註解來開啓CORS。默認@CrossOrigin容許全部的源和在@RequestMapping註解上指定的HTTP方法:web

@RestController
@RequestMapping("/account")
public class AccountController {

        @CrossOrigin
        @RequestMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
                // ...
        }

        @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
        public void remove(@PathVariable Long id) {
                // ...
        }
}

它也能夠在全部的控制器上開啓CORS:spring

@CrossOrigin(origins = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

        @RequestMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
                // ...
        }

        @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
        public void remove(@PathVariable Long id) {
                // ...
        }
}

在上面的例子中,對retrieve()remove()處理方法都開啓了CORS支持,你也能夠看到你能夠經過@CrossOrigin的屬性來配置CORS。api

你甚至能夠在控制器級別和方法級別進行CORS配置。Spring將組合兩個註解的屬性來建立一個組合的CORS配置。跨域

@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {

        @CrossOrigin("http://domain2.com")
        @RequestMapping("/{id}")
        public Account retrieve(@PathVariable Long id) {
                // ...
        }

        @RequestMapping(method = RequestMethod.DELETE, path = "/{id}")
        public void remove(@PathVariable Long id) {
                // ...
        }
}

3.3 全局CORS配置

除了基於註解的細粒度配置,你也可能想要定義一些全局的CORS配置。這個與使用過濾器相似,可是能夠在Spring MVC中聲明跟加上@CrossOrigin的細粒度配置。默認是容許全部的源跟GETHEADPOST方法。瀏覽器

3.3.1 JavaConfig

整個應用開啓CORS的例子以下:安全

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

        @Override
        public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**");
        }
}

你能夠輕鬆地改變任何屬性,也能夠將CORS配置指定到特殊的路徑模式:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

        @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);
        }
}

3.3.2 XML命名空間

下面的最小XML配置能夠在/**路徑模式下開啓CORS,具備跟前文提到的JavaConfig同樣的缺省屬性,例子:

<mvc:cors>
        <mvc:mapping path="/**" />
</mvc:cors>

它還能夠用定製的屬性來指定多個CORS映射:

<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>

3.4 高級定製

CorsConfiguration容許你指定CORS請求如何被處理:容許的源,頭信息,方法等等。它能夠以多種方式提供:

3.5 基於過濾器的CORS支持

爲了實現如Spring Security的基於過濾器的安全框架去支持CORS,或其餘原生不支持CORS的類庫,Spring框架也提供了CorsFilter。而不是使用@CrossOriginWebMvcConfigurer#addCorsMappings(CorsRegistry),你須要註冊一個以下的自定義過濾器:

import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

public class MyCorsFilter extends CorsFilter {

        public MyCorsFilter() {
                super(configurationSource());
        }

        private static UrlBasedCorsConfigurationSource configurationSource() {
                CorsConfiguration config = new CorsConfiguration();
                config.setAllowCredentials(true);
                config.addAllowedOrigin("http://domain1.com");
                config.addAllowedHeader("*");
                config.addAllowedMethod("*");
                UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
                source.registerCorsConfiguration("/**", config);
                return source;
        }
}

你須要確保CorsFilter在其餘過濾器以前,相應地看一下關於如何配置Spring Boot的這篇博客


【譯者注】 原文:http://docs.spring.io/spring/docs/5.0.0.RC1/spring-framework-reference/web.html#cors 看這篇文章以前,建議看一下阮一峯寫的關於CORS的文章 歡迎批評指正

相關文章
相關標籤/搜索