1. Обзор
В предыдущем посте мы узнали о спецификации совместного использования ресурсов между источниками (CORS) и о том , как ее использовать в Spring.
В этом кратком руководстве мы настроим аналогичную конфигурацию CORS с помощью Spring 5 WebFlux framework .
Прежде всего, мы посмотрим, как мы можем включить этот механизм в API на основе аннотаций.
Затем мы проанализируем, как включить его во всем проекте в качестве глобальной конфигурации или с помощью специального WebFilter .
2. Включение CORS для аннотированных элементов
Пружина обеспечивает @CrossOrigin аннотация для включения запросов CORS на классы контроллеров и/или методы обработчиков.
2.1. Использование @CrossOrigin в методе обработчика запросов
Давайте добавим эту аннотацию к нашему сопоставленному методу запроса:
@CrossOrigin
@PutMapping("/cors-enabled-endpoint")
public Mono corsEnabledEndpoint() {
// ...
} Мы будем использовать WebTestClient (как мы объяснили в разделе ‘4. Тестирование этого поста ) для анализа ответа, который мы получаем от этой конечной точки:
ResponseSpec response = webTestClient.put()
.uri("/cors-enabled-endpoint")
.header("Origin", "http://any-origin.com")
.exchange();
response.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "*");Кроме того, мы можем опробовать предполетный запрос, чтобы убедиться, что конфигурация CORS работает должным образом:
ResponseSpec response = webTestClient.options()
.uri("/cors-enabled-endpoint")
.header("Origin", "http://any-origin.com")
.header("Access-Control-Request-Method", "PUT")
.exchange();
response.expectHeader()
.valueEquals("Access-Control-Allow-Origin", "*");
response.expectHeader()
.valueEquals("Access-Control-Allow-Methods", "PUT");
response.expectHeader()
.exists("Access-Control-Max-Age");Аннотация @CrossOrigin имеет следующую конфигурацию по умолчанию:
- Разрешает все источники (это объясняет значение ” * ” в заголовке ответа)
- Разрешает все заголовки
- Все методы HTTP, сопоставленные методом обработчика, разрешены
- Учетные данные не включены
- Значение “Максимальный возраст” составляет 1800 секунд (30 минут)
Однако любое из этих значений может быть переопределено с помощью параметров аннотаций.
2.2. Использование @CrossOrigin на контроллере
Эта аннотация также поддерживается на уровне класса, и она повлияет на все его методы.
В случае, если конфигурация уровня класса не подходит для всех наших методов, мы можем аннотировать оба элемента, чтобы получить желаемый результат:
@CrossOrigin(value = { "http://allowed-origin.com" },
allowedHeaders = { "Baeldung-Allowed" },
maxAge = 900
)
@RestController
public class CorsOnClassController {
@PutMapping("/cors-enabled-endpoint")
public Mono corsEnabledEndpoint() {
// ...
}
@CrossOrigin({ "http://another-allowed-origin.com" })
@PutMapping("/endpoint-with-extra-origin-allowed")
public Mono corsEnabledWithExtraAllowedOrigin() {
// ...
}
// ...
} 3. Включение CORS в глобальной конфигурации
Мы также можем определить глобальную конфигурацию CORS, переопределив addCorsMappings() способ получения WebFluxConfigurer реализация.
Кроме того, реализация нуждается в аннотации @EnableWebFlux для импорта конфигурации веб-потока Spring в обычном приложении Spring. Если мы используем Spring Boot, то эта аннотация нужна нам только в том случае, если мы хотим переопределить автоматическую настройку:
@Configuration
@EnableWebFlux
public class CorsGlobalConfiguration implements WebFluxConfigurer {
@Override
public void addCorsMappings(CorsRegistry corsRegistry) {
corsRegistry.addMapping("/**")
.allowedOrigins("http://allowed-origin.com")
.allowedMethods("PUT")
.maxAge(3600);
}
}В результате мы включаем обработку запросов из разных источников для этого конкретного шаблона пути.
Конфигурация по умолчанию аналогична конфигурации @CrossOrigin , но разрешены только методы GET , HEAD и POST .
Мы также можем объединить эту конфигурацию с локальной:
- Для атрибутов с несколькими значениями результирующая конфигурация CORS будет дополнением каждой спецификации
- С другой стороны, локальные значения будут иметь приоритет над глобальными для однозначных значений
Однако использование этого подхода неэффективно для функциональных конечных точек.
4. Включение CORS с помощью веб-фильтра
Лучший способ включить CORS на функциональных конечных точках-это использовать Вебфильтр .
Как мы видели в этом посте , мы можем использовать Веб-фильтр s для изменения запросов и ответов, сохраняя при этом реализацию конечных точек нетронутой.
Пружина обеспечивает встроенный CorsWebFilter чтобы легко справляться с конфигурациями перекрестного происхождения:
@Bean
CorsWebFilter corsWebFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.setAllowedOrigins(Arrays.asList("http://allowed-origin.com"));
corsConfig.setMaxAge(8000L);
corsConfig.addAllowedMethod("PUT");
corsConfig.addAllowedHeader("Baeldung-Allowed");
UrlBasedCorsConfigurationSource source =
new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}Это также эффективно для аннотированных обработчиков, но его нельзя комбинировать с более мелкозернистой конфигурацией @CrossOrigin .
Мы должны иметь в виду, что конфигурация Cors не имеет конфигурации по умолчанию.
Таким образом, если мы не определим все соответствующие атрибуты, реализация CORS будет в значительной степени ограничительной.
Простым способом установки значений по умолчанию является использование применить значения Разрешения По Умолчанию() метод на объекте.
5. Заключение
В заключение мы ознакомились с очень короткими примерами того, как включить CORS в нашем веб-сервисе на основе потока.
Мы видели разные подходы, поэтому все, что нам сейчас нужно сделать, это проанализировать, какой из них лучше всего соответствует нашим требованиям.
Мы можем найти множество примеров в нашем репозитории GitHub , а также тестовые случаи, в которых мы анализируем большинство крайних случаев, связанных с этой темой.