web-dev-qa-db-fra.com

Spring CORS Aucun en-tête 'Access-Control-Allow-Origin' n'est présent.

Je reçois le problème suivant après le portage de web.xml vers Java config

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

Sur la base de quelques références Spring, la tentative suivante a été tentée:

@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);
    }

}

Les valeurs choisies ont été extraites d’un filtre web.xml actif:

<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>

Des idées sur la raison pour laquelle l’approche de configuration Spring Java ne fonctionne pas comme le fichier web.xml?

52
Ian Mc

Changez le CorsMapping de registry.addMapping("/*") en registry.addMapping("/**") dans la méthode addCorsMappings.

Découvrez ce printemps CORS Documentation .

De la documentation

Activer CORS pour l’ensemble de l’application est aussi simple que:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Vous pouvez facilement modifier les propriétés et appliquer uniquement cette configuration CORS à un modèle de chemin spécifique:

@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);
    }
}

Méthode de contrôleur CORS configuration

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

Pour activer le CORS pour l’ensemble du contrôleur -

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

Vous pouvez même utiliser à la fois des configurations CORS au niveau du contrôleur et au niveau de la méthode; Spring combinera ensuite les attributs des deux annotations pour créer une configuration CORS fusionnée.

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

Nous avons eu le même problème et nous l'avons résolu en utilisant la configuration XML de Spring comme ci-dessous: 

Ajoutez ceci dans votre fichier XML de contexte

<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>
7
Sabarish

Conseil utile - si vous utilisez des données Spring, vous devez adopter une approche différente.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

 @Override
 public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getCorsRegistry().addMapping("/**")
            .allowedOrigins("http://localhost:9000");
  }
}
6
ms.one

Si vous utilisez Spring Security ver> = 4.2, vous pouvez utiliser le support natif de Spring Security au lieu d'inclure celui d'Apache:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

L'exemple ci-dessus a été copié à partir d'un article de printemps blog dans lequel vous pouvez également trouver des informations sur la configuration de CORS sur un contrôleur, des méthodes de contrôleur spécifiques, etc. .

4
matsev

Suite à la réponse d'Omar, j'ai créé un nouveau fichier de classe dans mon projet d'API REST appelé WebConfig.Java avec cette configuration:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Cela permet à n’importe quelle origine d’accéder à l’API et de l’appliquer à tous les contrôleurs du projet Spring.

3
Shane

La réponse d'Omkar est assez complète.

Mais une partie de la configuration globale a changé.

Selon la référence spring boot 2.0.2.RELEASE

À partir de la version 4.2, Spring MVC prend en charge CORS. Utilisation de la méthode du contrôleur Configuration CORS avec des annotations @CrossOrigin dans votre Spring Boot l'application ne nécessite aucune configuration spécifique. Global CORS La configuration peut être définie en enregistrant un bean WebMvcConfigurer avec une méthode personnalisée addCorsMappings (CorsRegistry), comme indiqué dans l'exemple suivant:

@Configuration
public class MyConfiguration {

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

La plupart répondent dans ce post en utilisant WebMvcConfigurerAdapter, cependant

Le type WebMvcConfigurerAdapter est obsolète

Depuis le printemps 5, il ne vous reste plus qu'à implémenter l'interface WebMvcConfigurer:

public class MvcConfig implements WebMvcConfigurer {

En effet, Java 8 a introduit des méthodes par défaut sur les interfaces qui couvrir les fonctionnalités de la classe WebMvcConfigurerAdapter

2
Shihe Zhang

Pour une raison quelconque, si quelqu'un ne peut toujours pas contourner CORS, écrivez l'en-tête auquel le navigateur souhaite accéder.

Ajoutez ce haricot dans votre fichier de configuration.

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

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


        }
    };
}

De cette façon, nous pouvons dire au navigateur que nous autorisons l’origine croisée de toutes les origines. si vous souhaitez restreindre un chemin spécifique, remplacez le "*" par {' http: // localhost: 30 ', ""}.

Référence utile pour comprendre ce comportement https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example

0
Anshul Kabra

J'ai aussi eu des messages comme No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:63342' is therefore not allowed access.

J'avais configuré cors correctement, mais ce qui manquait dans webflux dans RouterFuncion était accept et les en-têtes contenttype APPLICATION_JSON comme dans ce morceau de code:

@Bean
RouterFunction<ServerResponse> routes() {
    return route(POST("/create")
                              .and(accept(APPLICATION_JSON))
                              .and(contentType(APPLICATION_JSON)), serverRequest -> create(serverRequest);
}
0
Rumid

comme @Geoffrey l'a fait remarquer, avec Spring Security, vous avez besoin d'une approche différente, comme décrit ici: Spring Boot Security CORS

0
womd