KORS mit Frühling

1. Übersicht

In jedem modernen Browser ist das Cross-Origin Resource Sharing (CORS) eine relevante Spezifikation mit dem Aufkommen von HTML5- und JS-Clients, die Daten über REST-APIs verbrauchen.

In vielen Fällen unterscheidet sich der Host, der das JS bedient (z. B. example.com ), von dem Host, der die Daten bedient (z . B. api.example.com ). In einem solchen Fall ermöglicht CORS die domänenübergreifende Kommunikation.

Spring bietet erstklassigen Support für CORS und bietet eine einfache und leistungsstarke Möglichkeit, es in jeder Spring- oder Spring Boot-Webanwendung zu konfigurieren.

2. Controller-Methode CORS-Konfiguration

Das Aktivieren von CORS ist unkompliziert - fügen Sie einfach die Anmerkung @CrossOrigin hinzu .

Wir können dies auf verschiedene Arten implementieren.

2.1. @CrossOrigin auf einer @ RequestMapping- Annotated-Handler-Methode

@RestController @RequestMapping("/account") public class AccountController { @CrossOrigin @RequestMapping(method = RequestMethod.GET, path = "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Im obigen Beispiel haben wir CORS nur für die Methode retrieve () aktiviert . Wir können sehen, dass wir keine Konfiguration für die @ CrossOrigin- Annotation festgelegt haben, daher werden die Standardeinstellungen verwendet:

  • Alle Ursprünge sind erlaubt
  • Die zulässigen HTTP-Methoden sind die in der Annotation @RequestMapping angegebenen (in diesem Beispiel GET).
  • Die Zeit, in der die Preflight-Antwort zwischengespeichert wird ( maxAge), beträgt 30 Minuten

2.2. @ CrossOrigin auf dem Controller

@CrossOrigin(origins = "//example.com", maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @RequestMapping(method = RequestMethod.GET, path = "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Dieses Mal haben wir @CrossOrigin auf Klassenebene hinzugefügt . Folglich haben sowohl die Methoden retrieve () als auch remove () diese Option aktiviert. Sie können die Konfiguration anpassen, indem Sie den Wert eines der Anmerkungsattribute angeben : Ursprünge , Methoden , allowHeaders , exponierteHeaders , allowCredentials oder maxAge.

2.3. @ CrossOrigin auf Controller- und Handler-Methode

@CrossOrigin(maxAge = 3600) @RestController @RequestMapping("/account") public class AccountController { @CrossOrigin("//example.com") @RequestMapping(method = RequestMethod.GET, "/{id}") public Account retrieve(@PathVariable Long id) { // ... } @RequestMapping(method = RequestMethod.DELETE, path = "/{id}") public void remove(@PathVariable Long id) { // ... } }

Spring kombiniert Attribute aus beiden Anmerkungen, um eine zusammengeführte CORS-Konfiguration zu erstellen.

In diesem Beispiel haben beide Methoden eine maximale Größe von 3600 Sekunden. Die Methode remove () lässt alle Ursprünge zu, die Methode retrieve () lässt jedoch nur Ursprünge von //example.com zu.

3. Globale CORS-Konfiguration

Als Alternative zur detaillierten Annotation-basierten Konfiguration können wir mit Spring einige globale CORS-Konfigurationen aus Ihren Controllern heraus definieren. Dies ähnelt der Verwendung einer Filter- basierten Lösung, kann jedoch in Spring MVC deklariert und mit einer feinkörnigen @ CrossOrigin- Konfiguration kombiniert werden .

Standardmäßig sind alle Ursprungs- und GET-, HEAD- und POST-Methoden zulässig.

3.1. JavaConfig

@Configuration @EnableWebMvc public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**"); } }

Das obige Beispiel aktiviert CORS-Anforderungen von einem beliebigen Ursprung an einen beliebigen Endpunkt in der Anwendung.

Wenn wir dies etwas weiter sperren möchten, gibt die Methode registry.addMapping ein CorsRegistration- Objekt zurück, das wir für zusätzliche Konfigurationen verwenden können. Es gibt auch eine allowOrigins- Methode, mit der wir ein Array zulässiger Ursprünge angeben können. Dies kann nützlich sein, wenn wir dieses Array zur Laufzeit von einer externen Quelle laden müssen.

Darüber hinaus gibt es allowMethods , allowHeaders , exponierteHeaders , maxAge und allowCredentials , mit denen wir die Antwortheader und Anpassungsoptionen festlegen können.

3.2. XML-Namespace

Diese minimale XML-Konfiguration aktiviert CORS in einem / ** -Pfadmuster mit denselben Standardeigenschaften wie die JavaConfig-Konfiguration:

Es ist auch möglich, mehrere CORS-Zuordnungen mit benutzerdefinierten Eigenschaften zu deklarieren:

4. CORS mit Federsicherheit

Wenn wir die Spring Security in unserem Projekt verwenden, müssen wir einen zusätzlichen Schritt unternehmen, um sicherzustellen, dass sie mit CORS gut funktioniert. Das liegt daran, dass CORS zuerst verarbeitet werden muss. Andernfalls lehnt Spring Security die Anforderung ab, bevor sie Spring MVC erreicht.

Glücklicherweise bietet Spring Security eine sofort einsatzbereite Lösung:

@EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http.cors().and()... } }

Dieser Artikel erklärt es ausführlicher.

5. Wie es funktioniert

CORS-Anforderungen werden automatisch an die verschiedenen registrierten HandlerMappings gesendet . Sie verarbeiten CORS-Preflight-Anforderungen und fangen einfache und tatsächliche CORS-Anforderungen mithilfe einer CorsProcessor- Implementierung ( standardmäßig DefaultCorsProcessor ) ab, um die relevanten CORS- Antwortheader (z. B. Access-Control-Allow-Origin ) hinzuzufügen .

Mit CorsConfiguration können wir festlegen, wie die CORS-Anforderungen verarbeitet werden sollen: unter anderem zulässige Ursprünge, Header und Methoden. Wir können es auf verschiedene Arten bereitstellen:

  • AbstractHandlerMapping # setCorsConfiguration () ermöglicht die Angabe einer Karte mit mehreren CorsConfiguration-Elementen, die Pfadmustern wie / api / ** zugeordnet sind
  • Subclasses may provide their own CorsConfiguration by overriding the AbstractHandlerMapping#getCorsConfiguration(Object, HttpServletRequest) method
  • Handlers may implement the CorsConfigurationSource interface (like ResourceHttpRequestHandler now does) to provide a CorsConfiguration for each request

6. Conclusion

In this article, we showed how Spring provides support for enabling CORS in our application.

We started with the configuration of the controller. We saw that we only need to add the annotation @CrossOrigin to enable CORS either to one particular method or the entire controller.

Schließlich haben wir auch gesehen, dass wir, wenn wir die CORS-Konfiguration außerhalb der Controller steuern möchten, dies reibungslos in den Konfigurationsdateien ausführen können - entweder mit JavaConfig oder XML.

Der vollständige Quellcode für die Beispiele ist auf GitHub verfügbar.