CORS с пролет

1. Общ преглед

Във всеки съвременен браузър Cross-Origin Resource Sharing (CORS) е подходяща спецификация с появата на HTML5 и JS клиенти, които консумират данни чрез REST API.

В много случаи хостът, който обслужва JS (например example.com ), се различава от хоста, който обслужва данните (например api.example.com ). В такъв случай CORS позволява комуникация между домейни.

Spring осигурява първокласна поддръжка за CORS, предлагайки лесен и мощен начин за конфигурирането му във всяко уеб приложение Spring или Spring Boot.

2. Метод на контролера CORS конфигурация

Активирането на CORS е лесно - просто добавете пояснението @CrossOrigin .

Можем да приложим това по няколко различни начина.

2.1. @CrossOrigin на @ RequestMapping- Annotated Handler Method

@RestController @RequestMapping("/account") public class AccountController { @CrossOrigin @RequestMapping(method = RequestMethod.GET, path = "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

В горния пример активирахме CORS само за метода retrieve () . Виждаме, че не сме задали никаква конфигурация за анотацията @CrossOrigin , така че тя използва настройките по подразбиране:

  • Всички произходи са разрешени
  • Разрешените HTTP методи са тези, посочени в анотацията @RequestMapping (за този пример е GET)
  • Времето за кеширане на предпечатната реакция ( maxAge) е 30 минути

2.2. @CrossOrigin на контролера

@CrossOrigin(origins = "//example.com", maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @RequestMapping(method = RequestMethod.GET, path = "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Този път добавихме @CrossOrigin на ниво клас. Следователно методите retrieve () и remove () го активират. Можем да персонализираме конфигурацията, като посочим стойността на един от атрибутите на анотацията: източници , методи , разрешени глави , експонирани глави , разрешени идентификационни данни или maxAge.

2.3. @CrossOrigin за метод на контролер и манипулатор

@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin("//example.com") @RequestMapping(method = RequestMethod.GET, "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Spring ще комбинира атрибути от двете анотации, за да създаде обединена CORS конфигурация.

В този пример и двата метода ще имат maxAge от 3600 секунди, методът remove () ще разреши всички източници, но методът retrieve () ще позволи само произход от //example.com.

3. Глобална конфигурация на CORS

Като алтернатива на фината конфигурация, базирана на анотации, Spring ни позволява да дефинираме някои глобални CORS конфигурации от вашите контролери. Това е подобно на използването на решение на базата на филтър, но може да бъде декларирано в Spring MVC и комбинирано с фино конфигурирана @CrossOrigin конфигурация

По подразбиране са разрешени всички източници и методи GET, HEAD и POST.

3.1. JavaConfig

@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } }

Примерът по-горе позволява CORS заявки от произволен произход до всяка крайна точка в приложението.

Ако искаме да заключим това още малко, методът registry.addMapping връща обект CorsRegistration , който можем да използваме за допълнителна конфигурация. Съществува и метод allowedOrigins , който ни позволява да посочим масив от разрешени източници. Това може да бъде полезно, ако трябва да заредим този масив от външен източник по време на изпълнение.

Освен това има разрешени методи , разрешени глави , експонирани глави , maxAge и allowCredentials, които можем да използваме, за да зададем заглавките на отговорите и опциите за персонализиране.

3.2. XML пространство от имена

Тази минимална XML конфигурация позволява CORS на / ** модел на пътя със същите свойства по подразбиране като JavaConfig:

Също така е възможно да декларирате няколко CORS съпоставяния с персонализирани свойства:

4. CORS с Spring Security

Ако използваме Spring Security в нашия проект, трябва да направим допълнителна стъпка, за да сме сигурни, че играе добре с CORS. Това е така, защото CORS трябва първо да бъдат обработени. В противен случай Spring Security ще отхвърли заявката, преди да достигне Spring MVC.

За щастие Spring Security предлага едно готово решение:

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

Тази статия го обяснява по-подробно.

5. Как работи

Исканията за CORS се изпращат автоматично до различните регистрирани HandlerMappings . Те обработват CORS предварителни заявки и прихващат CORS прости и действителни заявки, използвайки изпълнение на CorsProcessor ( DefaultCorsProcessor по подразбиране), за да добавят съответните заглавки на CORS отговор (като Access-Control-Allow-Origin ).

CorsConfiguration ни позволява да посочим как трябва да се обработват заявките CORS: разрешени източници, заглавки и методи, наред с други. Можем да го предоставим по различни начини:

  • AbstractHandlerMapping # setCorsConfiguration () позволява да се посочи карта с няколко CorsConfiguration s, нанесени върху модели на пътеки като / api / **
  • Подкласове могат да предоставят свои собствени CorsConfiguration с императивни на AbstractHandlerMapping # getCorsConfiguration (Object, HttpServletRequest) метод
  • Манипулаторите могат да внедрят интерфейса CorsConfigurationSource (като ResourceHttpRequestHandler сега), за да предоставят CorsConfiguration за всяка заявка

6. Заключение

В тази статия показахме как Spring предоставя поддръжка за активиране на CORS в нашето приложение.

Започнахме с конфигурацията на контролера. Видяхме, че трябва само да добавим анотацията @CrossOrigin, за да активираме CORS или към един конкретен метод, или към целия контролер.

И накрая, също така видяхме, че ако искаме да контролираме конфигурацията CORS извън контролерите, можем да изпълним това безпроблемно в конфигурационните файлове - използвайки JavaConfig или XML.

Пълният изходен код за примерите е достъпен на GitHub.