Spring CORS Es ist kein Header 'Access-Control-Allow-Origin' vorhanden

82

Ich erhalte das folgende Problem, nachdem ich web.xml nach Java Config portiert habe

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

Basierend auf einigen Spring-Referenzen wurde der folgende Versuch versucht:

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

}

Die ausgewählten Werte wurden einem funktionierenden web.xml-Filter entnommen:

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

Irgendwelche Ideen, warum der Spring Java-Konfigurationsansatz nicht wie die Datei web.xml funktioniert?

Ian Mc
quelle

Antworten:

110

Ändern Sie das CorsMapping von registry.addMapping("/*")in registry.addMapping("/**")inaddCorsMappings Methode .

Lesen Sie diese Spring CORS- Dokumentation .

Aus der Dokumentation -

Das Aktivieren von CORS für die gesamte Anwendung ist so einfach wie:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Sie können alle Eigenschaften einfach ändern und diese CORS-Konfiguration nur auf ein bestimmtes Pfadmuster anwenden:

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

Controller-Methode CORS-Konfiguration

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

So aktivieren Sie CORS für den gesamten 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) {
        // ...
    }
}

Sie können sogar CORS-Konfigurationen auf Controller- und Methodenebene verwenden. Spring kombiniert dann Attribute aus beiden Anmerkungen, um eine zusammengeführte CORS-Konfiguration zu erstellen.

@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) {
        // ...
    }
}
Omkar
quelle
35
Das Aktivieren von CORS für die gesamte Anwendung funktioniert bei mir nicht.
Dimitri Kopriwa
4
Die Verwendung addCorsMappinghat bei mir nicht funktioniert, ich bin versucht zu sagen, dass dies auf die Sicherheit des Frühlings zurückzuführen ist. Das Hinzufügen einer corsConfigurationSourceBohne, wie hier vorgeschlagen, hat mein Problem jedoch gelöst.
Geoffrey
1
Außerdem sollte nicht vergessen werden, alle Clients zuzulassen. Registry.addMapping ("/ **"). PermiredOrigins ("*"); spring.io/guides/gs/rest-service-cors
spacedev
1
Du bist wirklich ein Lebensretter. Ich verwende Spring 4.2 und habe unzählige andere Alternativen ausprobiert. Alle funktionieren einfach erst, wenn ich versucht habe, die addCorsMappings zu überschreiben. Kann oder kann nicht geholfen wird der Standard-CORS-Header sowie Access-Control-Allow-Header
Vyrnach
2
Die Annotation für 2020 und Spring Boot funktioniert immer noch nicht.
Programmierer
13

Hilfreicher Tipp - Wenn Sie Spring Data Rest verwenden, benötigen Sie einen anderen Ansatz.

@Component
public class SpringDataRestCustomization extends RepositoryRestConfigurerAdapter {

 @Override
 public void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
    config.getCorsRegistry().addMapping("/**")
            .allowedOrigins("http://localhost:9000");
  }
}
rückwärts binden
quelle
3
Danke für diesen Beitrag. Ich habe irgendwie die Hoffnung verloren, als ich in Ihrem Beitrag bemerkte, dass Spring Data REST einen anderen Ansatz verwendet. Funktioniert jetzt total für mich!
Jonathan Crégut
1
RepositoryRestConfigurerAdapterist veraltet. Implementiert einfach RepositoryRestConfigurerdirekt.
Gustavo Rodrigues
9

Wir hatten das gleiche Problem und haben es mithilfe der folgenden XML-Konfiguration von Spring behoben:

Fügen Sie dies in Ihre Kontext-XML-Datei ein

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

Wenn Sie Spring Security Version> = 4.2 verwenden, können Sie die native Unterstützung von Spring Security verwenden, anstatt die von Apache einzuschließen:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Das obige Beispiel wurde aus einem Spring- Blogbeitrag kopiert, in dem Sie auch Informationen zum Konfigurieren von CORS auf einem Controller, zu bestimmten Controller-Methoden usw. finden. Darüber hinaus gibt es auch XML-Konfigurationsbeispiele sowie die Spring Boot-Integration.

matsev
quelle
4

Nach Omars Antwort habe ich in meinem REST-API-Projekt eine neue Klassendatei WebConfig.javamit der folgenden Konfiguration erstellt:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

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

Dadurch kann jeder Ursprung auf die API zugreifen und sie auf alle Controller im Spring-Projekt anwenden.

Shane
quelle
4

Omkars Antwort ist ziemlich umfassend.

Ein Teil des globalen Konfigurationsteils hat sich jedoch geändert.

Gemäß der Referenz zum Federmanschetten 2.0.2.RELEASE

Ab Version 4.2 unterstützt Spring MVC CORS. Für die Verwendung der CORS-Konfiguration der Controller-Methode mit @ CrossOrigin-Annotationen in Ihrer Spring Boot-Anwendung ist keine spezielle Konfiguration erforderlich. Die globale CORS-Konfiguration kann definiert werden, indem eine WebMvcConfigurer-Bean mit einer angepassten Methode addCorsMappings (CorsRegistry) registriert wird, wie im folgenden Beispiel gezeigt:

@Configuration
public class MyConfiguration {

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

Die meisten Antworten in diesem Beitrag verwenden WebMvcConfigurerAdapterjedoch

Der Typ WebMvcConfigurerAdapter ist veraltet

Seit Spring 5 müssen Sie nur noch die Schnittstelle WebMvcConfigurer implementieren:

public class MvcConfig implements WebMvcConfigurer {

Dies liegt daran, dass Java 8 Standardmethoden für Schnittstellen eingeführt hat, die die Funktionalität der WebMvcConfigurerAdapter-Klasse abdecken

Shihe Zhang
quelle
0

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

Ich hatte cors richtig konfiguriert, aber was im Webflux in RouterFuncion fehlte, war Accept und Content-Type-Header APPLICATION_JSON wie in diesem Code:

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

Wie @Geoffrey betonte, benötigen Sie bei Spring Security einen anderen Ansatz als hier beschrieben: Spring Boot Security CORS

Frau
quelle
0

Wenn aus irgendeinem Grund immer noch jemand nicht in der Lage ist, CORS zu umgehen, schreiben Sie den Header, über den der Browser auf Ihre Anfrage zugreifen möchte.

Fügen Sie diese Bean in Ihre Konfigurationsdatei ein.

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

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


        }
    };
}

Auf diese Weise können wir dem Browser mitteilen, dass wir Cross-Origin von allen Ursprüngen zulassen. Wenn Sie einen bestimmten Pfad einschränken möchten, ändern Sie das "*" in {' http: // localhost: 3000 ', ""}.

Hilfreiche Referenz zum Verständnis dieses Verhaltens https://www.concretepage.com/spring-4/spring-4-rest-cors-integration-using-crossorigin-annotation-xml-filter-example

Anshul Kabra
quelle
0

Ich habe die Lösung im Frühjahrsstart mithilfe der Annotation @CrossOrigin gefunden .

@RestController
@CrossOrigin
public class WebConfig extends WebMvcConfigurerAdapter {

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

öffentliche Klasse 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");
            }
        };
    }

}
Avinash Khadsan
quelle