Spring CORS Нет заголовка Access-Control-Allow-Origin

89

После переноса web.xml в конфигурацию java у меня возникает следующая проблема

No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

Основываясь на нескольких ссылках на Spring, была предпринята следующая попытка:

@Configuration
@ComponentScan(basePackageClasses = AppConfig.class, useDefaultFilters = false, includeFilters = {
        @Filter(org.springframework.stereotype.Controller.class) })
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*").allowedOrigins("*").allowedMethods("GET", "POST", "OPTIONS", "PUT")
                .allowedHeaders("Content-Type", "X-Requested-With", "accept", "Origin", "Access-Control-Request-Method",
                        "Access-Control-Request-Headers")
                .exposedHeaders("Access-Control-Allow-Origin", "Access-Control-Allow-Credentials")
                .allowCredentials(true).maxAge(3600);
    }

}

Выбранные значения были взяты из работающего фильтра web.xml:

<filter>    
<filter-name>CorsFilter</filter-name>
<filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
<init-param>
    <param-name>cors.allowed.origins</param-name>
    <param-value>*</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.methods</param-name>
    <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
</init-param>
<init-param>
    <param-name>cors.allowed.headers</param-name>
    <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers</param-value>
</init-param>
<init-param>
    <param-name>cors.exposed.headers</param-name>
    <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
</init-param>
<init-param>
    <param-name>cors.support.credentials</param-name>
    <param-value>true</param-value>
</init-param>
<init-param>
    <param-name>cors.preflight.maxage</param-name>
    <param-value>10</param-value>
</init-param> </filter> <filter-mapping>

<filter-name>CorsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

Есть идеи, почему подход Spring java config не работает так, как файл web.xml?

Иэн Мак
источник

Ответы:

115

Измените метод CorsMapping с registry.addMapping("/*")на registry.addMapping("/**")in addCorsMappings.

Ознакомьтесь с этой Spring документацией CORS .

Из документации -

Включить 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);
    }
}

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

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

Чтобы включить CORS для всего контроллера -

@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) {
        // ...
    }
}

Вы даже можете использовать конфигурации 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) {
        // ...
    }
}
Омкар Путтагунта
источник
37
Включение CORS для всего приложения у меня не работает.
Dimitri Kopriwa 03
4
Использование addCorsMappingне сработало для меня, хотелось сказать, что это из-за весенней безопасности ..., однако добавление corsConfigurationSourcebean-компонента, как здесь предлагается, решило мою проблему.
Джеффри
1
Также не следует забывать разрешить всем клиентам registry.addMapping ("/ **"). AllowedOrigins ("*"); spring.io/guides/gs/rest-service-cors
spacedev
1
ты действительно спасатель. Я использую Spring 4.2 и пробовал бесчисленное множество других альтернатив, и все они просто не работали, пока я не попробовал переопределить addCorsMappings. Может помочь, а может и нет, добавлен стандартный заголовок CORS, а также Access-Control-Allow-Headers
Vyrnach
2
Аннотации загрузки 2020 и Spring по-прежнему не работают.
theprogrammer
15

Полезный совет - если вы используете Spring data rest, вам нужен другой подход.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

 @Override
 public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getCorsRegistry().addMapping("/**")
            .allowedOrigins("http://localhost:9000");
  }
}
обратная связь
источник
3
Спасибо за этот пост. Я как бы терял надежду, когда заметил ваше сообщение о том, что Spring Data REST использует другой подход. У меня теперь полностью работает!
Джонатан Крегут
2
RepositoryRestConfigurerAdapterустарел. Просто реализует RepositoryRestConfigurerнапрямую.
Густаво Родригес,
11

У нас была такая же проблема, и мы решили ее, используя конфигурацию XML Spring, как показано ниже:

Добавьте это в свой контекстный xml файл

<mvc:cors>
    <mvc:mapping path="/**"
        allowed-origins="*"
        allowed-headers="Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Authorization, X-Requested-With, requestId, Correlation-Id"
        allowed-methods="GET, PUT, POST, DELETE"/>
</mvc:cors>
Сабариш
источник
5

Если вы используете Spring Security ver> = 4.2, вы можете использовать встроенную поддержку Spring Security вместо включения Apache:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Приведенный выше пример был скопирован из сообщения в блоге Spring, в котором вы также можете найти информацию о том, как настроить CORS на контроллере, конкретных методах контроллера и т. Д. Кроме того, есть также примеры конфигурации XML, а также интеграция Spring Boot.

Мацев
источник
5

Следуя ответу Омара, я создал новый файл класса в своем проекте REST API WebConfig.javaс такой конфигурацией:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Это позволяет любому источнику получить доступ к API и применяет его ко всем контроллерам в проекте Spring.

Шейн
источник
5

Ответ Омкара довольно исчерпывающий.

Но какая-то часть глобальной конфигурации изменилась.

По ссылке spring boot 2.0.2.RELEASE

Начиная с версии 4.2 Spring MVC поддерживает CORS. Использование метода управления CORS с аннотациями @CrossOrigin в приложении Spring Boot не требует какой-либо конкретной настройки. Глобальную конфигурацию CORS можно определить, зарегистрировав bean-компонент WebMvcConfigurer с помощью настроенного метода addCorsMappings (CorsRegistry), как показано в следующем примере:

@Configuration
public class MyConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }
        };
    }
}

Большинство ответов в этом сообщении WebMvcConfigurerAdapter, однако

Тип WebMvcConfigurerAdapter устарел.

Начиная с Spring 5 вам просто нужно реализовать интерфейс WebMvcConfigurer:

public class MvcConfig implements WebMvcConfigurer {

Это связано с тем, что Java 8 представила методы по умолчанию для интерфейсов, которые охватывают функциональность класса WebMvcConfigurerAdapter.

Шихэ Чжан
источник
2

public class TrackingSystemApplication {

    public static void main(String[] args) {
        SpringApplication.run(TrackingSystemApplication.class, args);
    }

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurerAdapter() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**").allowedOrigins("http://localhost:4200").allowedMethods("PUT", "DELETE",
                        "GET", "POST");
            }
        };
    }

}
Авинаш Хадсан
источник
0

У меня также были сообщения вроде No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

Я правильно настроил cors, но в webflux в RouterFuncion не хватало заголовков accept и contenttype APPLICATION_JSON, как в этом фрагменте кода:

@Bean
RouterFunction<ServerResponse> routes() {
    return route(POST("/create")
                              .and(accept(APPLICATION_JSON))
                              .and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}
Грубый
источник
0

как отметил @Geoffrey, с весенней безопасностью вам нужен другой подход, как описано здесь: Spring Boot Security CORS

женщина
источник
0

По какой-то причине, если все же кто-то не может обойти CORS, напишите заголовок, браузер которого хочет получить доступ к вашему запросу.

Добавьте этот bean-компонент в свой файл конфигурации.

@Bean
public WebSecurityConfigurerAdapter webSecurity() {
    return new WebSecurityConfigurerAdapter() {

        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.headers().addHeaderWriter(
                    new StaticHeadersWriter("Access-Control-Allow-Origin", "*"));


        }
    };
}

Таким образом, мы можем сказать браузеру, что разрешаем перекрестное происхождение из любого источника. если вы хотите ограничиться определенным путем, измените "*" на {' http: // localhost: 3000 ', ""}.

Полезная ссылка для понимания этого поведения https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example

Аншул Кабра
источник
0

Я нашел решение в весенней загрузке с помощью аннотации @CrossOrigin .

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
НафазБензема
источник