wake-up-neo.net

Spring Global CORS-Konfiguration funktioniert nicht, Controller-Ebene konfiguriert

Ich versuche, CORS global über die unten gezeigte WebMvcConfigurerAdapter zu konfigurieren. Zum Testen erreiche ich meinen API-Endpunkt über eine kleine Knoten-App, die ich erstellt habe, um einen externen Dienst zu emulieren. Wenn ich diesen Ansatz versuche, enthält die Antwort nicht die richtigen Header und schlägt fehl 

XMLHttpRequest cannot load http://localhost:8080/api/query/1121. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:333' is therefore not allowed access.

Globale Konfig

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@EnableWebMvc
@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/api/query/**")
                    .allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowCredentials(true);
        }
}

Wenn ich jedoch die @CrossOrigin-Annotation verwende, funktioniert es gut, wenn Sie mit den richtigen Headern antworten.

@CrossOrigin(origins = "*", allowCredentials = "true", allowedHeaders = "*")
@RestController
@RequestMapping(value = "/api/query", produces = MediaType.APPLICATION_JSON_VALUE)
public class QueryController {
   ......
}

Produziert

Access-Control-Allow-Credentials:true
Access-Control-Allow-Origin:http://localhost:333

Was fehlt mir, um die globale Konfiguration funktionieren zu lassen (Anweisungen hier https://spring.io/blog/2015/06/08/cors-support-in-spring-framework ). Ich habe das Gefühl, dass mir etwas Einfaches fehlt, da das Kommentieren des Controllers gut funktioniert.

24
Adam James

Damit die globale CORS-Konfiguration funktionieren kann, muss der Client diese beiden Header in der Anforderung OPTIONS hinzufügen.

Origin: http://Host.com
Access-Control-Request-Method: POST

Die Annotation @CrossOrigin erfordert jedoch nur den "Origin" -Header.
Ihr Client fügt wahrscheinlich den "Origin" -Header hinzu, es fehlt jedoch die "Access-Control-Request-Methode" ..... deshalb funktioniert es für Sie mit der @ CrossOrigin, aber nicht mit der globalen Konfiguration. 

13
outdev

sie haben keine Methode darin deklariert, die standardmäßig nur die get-Methode akzeptiert. _. try registry.allowedMethods("*"); 

4

Ich konnte die Spring Global CORS-Konfiguration zum Laufen bringen, nachdem ich genau das in diesem Problem beschriebene Problem festgestellt hatte. Ich musste 2 Dinge tun:

  1. allowOrigins kann nicht * sein, wenn allowCredentials wahr ist. Dies ist auf Mozilla.org dokumentiert

  2. Entfernen Sie mvc: annotation-driven aus der Feder-XML. Kann BEIDE die XML-Konfiguration und @EnableWebMvc nicht haben. Die globale Klasse funktioniert nicht ohne @EnableWebMvc. Daher muss mvc: annotation-driven entfernt werden.

2
user9124560

Ich habe gerade genau das gleiche Problem gehabt, wobei keine der Lösungen in diesem Thread funktioniert. Ich habe es geschafft, mit dem folgenden zu lösen:

Eine neue Konfigurations-Bean:

@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilterConfiguration {

  @Bean
  public CorsFilter corsFilter() {
      UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
      CorsConfiguration config = new CorsConfiguration();
      config.setAllowCredentials(true);
      config.addAllowedOrigin("*");
      config.setAllowedMethods(Arrays.asList("POST", "OPTIONS", "GET", "DELETE", "PUT"));
      config.setAllowedHeaders(Arrays.asList("X-Requested-With", "Origin", "Content-Type", "Accept", "Authorization"));
      source.registerCorsConfiguration("/**", config);
      return new CorsFilter(source);
  }
}

Eine Änderung an meiner web.xml, um einen neuen Filter für alle URLs hinzuzufügen:

<filter>
  <filter-name>corsFilter</filter-name>
  <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
  <filter-name>corsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Natürlich können Sie die cors config entsprechend anpassen.

1
Tom

Ich war mit einem ähnlichen Problem konfrontiert. Ich habe den WebMvcConfigurerAdapter in WebMvcConfigurationSupport geändert und der Betrieb begann.

Darüber hinaus habe ich auch das in XML-Konfigurationsdatei definierte RequestMappingHandlerMapping in die Java-Konfiguration verschoben.

1
Bharat Singh

Ich denke, Ihrer Mapping-Definition fehlt ein *:

registry.addMapping("/api/query/**")

Ohne diesen zusätzlichen * wird diese Konfiguration nicht dem Anforderungspfad /api/query/1121 zugeordnet (würde jedoch mit /api/query/5 funktionieren).

0
Brian Clozel

Ich hatte das gleiche Problem und nachdem ich das maxAge Attribut gesetzt hatte, fing alles an zu funktionieren.

@Bean
public WebMvcConfigurer CORSConfigurer() {
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("*")
                    .allowedHeaders("*")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                    .maxAge(-1)   // add maxAge
                    .allowCredentials(false);
        }
    };
}

wenn Sie die Annotation CrossOrigin aktivieren, wird diesem Attribut ein Standardwert zugewiesen

/**
 * <p>By default this is set to {@code 1800} seconds (30 minutes).
 */
long maxAge() default -1;
0
Jorge L. Morla

Ich hatte ein ähnliches Problem und keine der Methoden schien zu funktionieren (mit Ausnahme der @CrossOrigin-Annotation für jeden Controller). Ich folgte der Bharat Singh's - Lösung oben und nach einigem Debuggen von Spring Framework-Interna - hier ist was für mich funktioniert (Spring Boot 2.0.6 + Spring Framework 5.0.10):

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {

/* (non-Javadoc)
 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#addCorsMappings(org.springframework.web.servlet.config.annotation.CorsRegistry)
 */
@Override
protected void addCorsMappings(CorsRegistry registry) {
    //NOTE: servlet context set in "application.properties" is "/api" and request like "/api/session/login" resolves here to "/session/login"!
    registry.addMapping("/**")
        .allowedMethods("GET", "POST", "PUT", "DELETE")
        .allowedOrigins("*")
        .allowedHeaders("*")
        .allowCredentials(false);
    }
}

Als ich "/api/**"-Mapping verwendet habe, wurde es zunächst in Spring konfiguriert. Da die Anwendung jedoch mit "/api" context implementiert wurde, wurden Anforderungen wie "/api/session/login" intern auf "/session/login" abgebildet. Diese Zuordnung in der CORS-Konfiguration wurde nicht gefunden. Bitte beachten Sie dies!

0