Автор Себастьян Делёз в блоге Spring
По соображениям безопасности браузеры запрещают вызовы AJAX ресурсам, находящимся вне текущего источника. Например, когда вы проверяете свой банковский счет на одной вкладке, у вас может быть сайт evil.com на другой вкладке. Скрипты с сайта evil.com не должны отправлять запросы AJAX на API вашего банка (снятие денег с вашего счета!) С использованием ваших учетных данных.
Распределение ресурсов между источниками (CORS) — это спецификация W3C, реализованная большинством браузеров, которая позволяет гибко указывать, какие типы запросов между доменами разрешены, вместо использования менее защищенных и менее мощных хаков, таких как IFrame или JSONP.
Недавно выпущенный Spring Framework 4.2 RC1 обеспечивает первоклассную поддержку CORS « из коробки», предоставляя вам более простой и мощный способ его настройки, чем типичные решения на основе фильтров .
Spring MVC предоставляет средства конфигурации высокого уровня, описанные ниже.
Контроллер метод настройки CORS
Вы можете добавить к своему @RequestMapping
методу аннотированного обработчика @CrossOrigin
аннотацию, чтобы включить для него CORS (по умолчанию @CrossOrigin
разрешены все источники и методы HTTP, указанные в @RequestMapping
аннотации):
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Также возможно включить CORS для всего контроллера:
@CrossOrigin(origin = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
В этом примере поддержка CORS включена для обоих методов retrieve()
и remove()
методов-обработчиков, и вы также можете увидеть, как можно настроить конфигурацию CORS с помощью @CrossOrigin
атрибутов.
Вы даже можете использовать конфигурации CORS как на уровне контроллера, так и на уровне метода. Spring объединит оба атрибута аннотации для создания объединенной конфигурации CORS.
@CrossOrigin(maxAge = 3600)
@RestController
@RequestMapping("/account")
public class AccountController {
@CrossOrigin(origin = "http://domain2.com")
@RequestMapping("/{id}")
public Account retrieve(@PathVariable Long id) {
// ...
}
@RequestMapping(method = RequestMethod.DELETE, value = "/{id}")
public void remove(@PathVariable Long id) {
// ...
}
}
Глобальная конфигурация CORS
В дополнение к детальной конфигурации на основе аннотаций вы, вероятно, захотите также определить некоторую глобальную конфигурацию CORS. Это похоже на использование фильтров, но может быть объявлено в Spring MVC и объединено с детальной @CrossOrigin
конфигурацией. По умолчанию разрешены все источники, и GET
, HEAD
и POST
методы.
API-интерфейс глобальной конфигурации изменился после Spring Framework 4.2 RC1, поэтому обязательно используйте текущую сборку 4.2.0.BUILD-SNAPSHOT или следующую версию 4.2.0.RC2.
JavaConfig
Включение CORS для всего приложения так же просто, как:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
}
Вы можете легко изменить любые свойства, а также применить эту конфигурацию CORS только к определенному шаблону пути:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@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);
}
}
Пространство имен XML
Начиная с Spring Framework 4.2 RC2 также будет возможно настроить CORS с пространством имен mvc 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>
Как это работает?
Запросы CORS ( включая предполетные с помощью OPTIONS
метода ) автоматически отправляются различным HandlerMapping
зарегистрированным. Они обрабатывают предварительные запросы CORS и перехватывают простые и актуальные запросы CORS благодаря реализации CorsProcessor ( по умолчанию DefaultCorsProcessor ) для добавления соответствующих заголовков ответов CORS (например Access-Control-Allow-Origin
). CorsConfiguration позволяет указать, как должны обрабатываться запросы CORS: разрешенные источники, заголовки, методы и т. Д. Это может быть предоставлено различными способами:
AbstractHandlerMapping#setCorsConfiguration()
позволяет указатьMap
с несколькими CorsConfiguration, сопоставленными с шаблонами пути, такими как/api/**
- Подклассы могут предоставлять свои собственные
CorsConfiguration
, переопределяяAbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)
метод - Обработчики могут реализовать
CorsConfigurationSource
интерфейс (какResourceHttpRequestHandler
сейчас), чтобы обеспечить CorsConfiguration для каждого запроса.
Интеграция Spring Boot
Поддержка CORS будет доступна в следующем выпуске Spring Boot 1.3 и уже доступна в сборках 1.3.0.BUILD-SNAPSHOT.
Если мелкозернистая конфигурация CORS уже идеально подходит для приложений Spring Boot, более вероятно, что в Spring Boot 1.3 будет предоставлен более «удобный» способ настройки глобальной конфигурации CORS (на основе объявления bean-компонента CorsConfiguration и выделенных свойств Spring Boot). Смотрите эту проблему для более подробной информации.
Как обычно, отзывы приветствуются!