Spring CORS Non è presente l'intestazione "Access-Control-Allow-Origin"


89

Sto riscontrando il seguente problema dopo il porting di web.xml in java config

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

Sulla base di alcuni riferimenti di primavera, è stato provato il seguente tentativo:

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

}

I valori scelti sono stati presi da un filtro web.xml funzionante:

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

Qualche idea sul perché l'approccio Spring java config non funzioni come il file web.xml?

Risposte:


115

Modificare il metodo CorsMapping da registry.addMapping("/*")a registry.addMapping("/**")in addCorsMappings.

Dai un'occhiata a questa documentazione di Spring CORS .

Dalla documentazione -

Abilitare CORS per l'intera applicazione è semplice come:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

È possibile modificare facilmente qualsiasi proprietà, nonché applicare questa configurazione CORS solo a un modello di percorso specifico:

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

Configurazione CORS metodo controller

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

Per abilitare CORS per l'intero controller:

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

È anche possibile utilizzare configurazioni CORS sia a livello di controller che a livello di metodo; Spring combinerà quindi gli attributi di entrambe le annotazioni per creare una configurazione CORS unita.

@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
L'abilitazione di CORS per l'intera applicazione non funziona per me.
— Dimitri Kopriwa

4
L'utilizzo addCorsMappingnon ha funzionato per me, sono tentato di dire che è a causa della sicurezza primaverile ..., tuttavia l'aggiunta di un corsConfigurationSourcefagiolo come suggerito qui ha risolto il mio problema.
— Geoffrey

1
Inoltre, non dimenticare di consentire a tutti i client registry.addMapping ("/ **"). AllowedOrigins ("*"); spring.io/guides/gs/rest-service-cors
— spacedev

1
sei veramente un salvavita. Sto usando Spring 4.2 e ho provato innumerevoli altre alternative e tutte semplicemente non funzionano fino a quando non ho provato il modo di sovrascrivere addCorsMappings. Può o non può aiutato è aggiunto il CORS standard di intestazione così come Access-Control-Allow-Headers
— Vyrnach

2
È il 2020 e l'annotazione di avvio primaverile non funziona ancora.
— programmatore

15

Suggerimento utile: se utilizzi il riposo dati primaverile, è necessario un approccio diverso.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

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

3
Grazie per questo post. Stavo perdendo la speranza quando ho notato che il tuo post diceva che Spring Data REST utilizza un approccio diverso. Funziona totalmente per me ora!
— Jonathan Crégut

2
RepositoryRestConfigurerAdapterè deprecato. Basta implementare RepositoryRestConfigurerdirettamente.
— Gustavo Rodrigues

11

Abbiamo avuto lo stesso problema e lo abbiamo risolto utilizzando la configurazione XML di Spring come di seguito:

Aggiungilo nel tuo file xml di contesto

<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

Se stai usando Spring Security ver> = 4.2 puoi usare il supporto nativo di Spring Security invece di includere Apache:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

L'esempio sopra è stato copiato da un post del blog di Spring in cui è anche possibile trovare informazioni su come configurare CORS su un controller, metodi di controller specifici, ecc. Inoltre, sono presenti anche esempi di configurazione XML e l'integrazione di Spring Boot.


5

Seguendo la risposta di Omar, ho creato un nuovo file di classe nel mio progetto API REST chiamato WebConfig.javacon questa configurazione:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Ciò consente a qualsiasi origine di accedere all'API e di applicarla a tutti i controller nel progetto Spring.


5

La risposta di Omkar è abbastanza esauriente.

Ma una parte della parte di configurazione globale è cambiata.

Secondo il riferimento Spring Boot 2.0.2.RELEASE

A partire dalla versione 4.2, Spring MVC supporta CORS. L'uso della configurazione CORS del metodo controller con annotazioni @CrossOrigin nell'applicazione Spring Boot non richiede alcuna configurazione specifica. La configurazione CORS globale può essere definita registrando un bean WebMvcConfigurer con un metodo addCorsMappings (CorsRegistry) personalizzato, come mostrato nell'esempio seguente:

@Configuration
public class MyConfiguration {

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

La maggior parte delle risposte in questo post utilizza WebMvcConfigurerAdapter, tuttavia

Il tipo WebMvcConfigurerAdapter è deprecato

Dalla Spring 5 è sufficiente implementare l'interfaccia WebMvcConfigurer:

public class MvcConfig implements WebMvcConfigurer {

Questo perché Java 8 ha introdotto metodi predefiniti sulle interfacce che coprono la funzionalità della classe 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

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

Avevo configurato correttamente cors, ma ciò che mancava in webflux in RouterFuncion era accettare e le intestazioni del tipo di contenuto APPLICATION_JSON come in questo pezzo di codice:

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


0

Per qualche motivo, se ancora qualcuno non è in grado di bypassare CORS, scrivi l'intestazione con cui il browser vuole accedere alla tua richiesta.

Aggiungi questo bean nel tuo file di configurazione.

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

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


        }
    };
}

In questo modo possiamo dire al browser che stiamo consentendo il cross-origin da qualsiasi origine. se desideri limitare il percorso da un percorso specifico, modifica "*" in {' http: // localhost: 3000 ', ""}.

Riferimento utile per comprendere questo comportamento https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example


0

Ho trovato la soluzione nell'avvio primaverile utilizzando l' annotazione @CrossOrigin .

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.