CORS с весны

CORS с пружиной

1. обзор

В любом современном браузере кросс-источник общего доступа к ресурсам (CORS) является актуальной спецификацией с появлением клиентов HTML5 и JS, которые используют данные через API REST.

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

Spring предоставляет первоклассныеsupport для CORS, предлагая простой и эффективный способ его настройки в любом веб-приложении Spring или Spring Boot.

Дальнейшее чтение:

Исправление 401 с предполетными полетами CORS и Spring Security

Узнайте, как исправить состояние ошибки HTTP 401 для запросов предварительной проверки CORS

Read more

Spring Webflux и CORS

Краткое и практическое руководство по работе с CORS и Spring Webflux.

Read more

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

Включить CORS просто - просто добавьте аннотацию@CrossOrigin.

Мы можем реализовать это несколькими различными способами.

2.1. @CrossOrigin в методе аннотированного обработчика@RequestMapping-

@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 включен только для методаretrieve(). Мы видим, что мы не задавали никакой конфигурации для аннотации@CrossOrigin, поэтому используется конфигурация по умолчанию:

  • Все источники разрешены

  • Разрешены методы HTTP, указанные в аннотации@RequestMapping (в этом примере - GET)

  • Время кеширования предполетного ответа (maxAge) составляет 30 минут

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

@CrossOrigin(origins = "http://example.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) {
        // ...
    }
}

Поскольку@CrossOrigin добавлен к контроллеру, оба методаretrieve() иremove() имеют его. Мы можем настроить конфигурацию, указав значение одного из атрибутов аннотации:origins,methods,allowedHeaders,exposedHeaders,allowCredentials илиmaxAge.

2.3. @CrossOrigin на Контроллер и метод обработчика

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

    @CrossOrigin("http://example.com")
    @RequestMapping("/{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() разрешит только источники изhttp://example.com.

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

В качестве альтернативы мелкозернистой конфигурации на основе аннотаций Spring позволяет нам определять некоторые глобальные конфигурации CORS из ваших контроллеров. Это похоже на использование решения на основеFilter, но может быть объявлено в Spring MVC и объединено с мелкозернистой конфигурацией@CrossOrigin.

По умолчанию разрешены все методы origin и 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, который можно использовать для указания массива разрешенных источников. Это может быть полезно, если вам нужно загрузить этот массив из внешнего источника во время выполнения.

Кроме того, есть такжеallowedMethods,allowedHeaders,exposedHeaders,maxAge иallowCredentials, которые можно использовать для установки заголовков ответов и предоставления дополнительных параметров настройки. .

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

Эта минимальная конфигурация XML позволяет CORS использовать шаблон пути/** с теми же свойствами по умолчанию, что и у JavaConfig:


    

Также возможно объявить несколько отображений CORS с настроенными свойствами:



    

    

4. Как это устроено

Запросы CORS автоматически отправляются различным зарегистрированнымHandlerMappings. Они обрабатывают предварительные запросы CORS и перехватывают простые и фактические запросы CORS с помощью реализацииCorsProcessor (по умолчаниюDefaultCorsProcessor), чтобы добавить соответствующие заголовки ответов CORS (например,Access-Control-Allow-Origin).

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

  • AbstractHandlerMapping#setCorsConfiguration() позволяет указатьMap с несколькимиCorsConfiguration, отображенными на шаблоны пути, такие как/api/**

  • Подклассы могут предоставлять свои собственныеCorsConfiguration путем переопределения методаAbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest)

  • Обработчики могут реализовать интерфейсCorsConfigurationSource (как сейчас делаетResourceHttpRequestHandler), чтобы предоставлятьCorsConfiguration для каждого запроса.

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

В этой статье мы показали, как Spring обеспечивает поддержку включения CORS в нашем приложении.

Мы начали с настройки контроллера. Мы видели, что нам нужно только добавить аннотацию@CrossOrigin, чтобы включить CORS либо для одного конкретного метода, либо для всего контроллера.

Наконец, мы также увидели, что если мы хотим контролировать конфигурацию CORS вне контроллеров, мы можем легко выполнить это в файлах конфигурации - используя JavaConfig или XML.

Полный исходный код примеров доступенover on GitHub.