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.