OPTIONS statt PUT oder POST

HTML Apps sind im Grunde relativ unsicher. Der Benutzer kann beliebigen Code laden und sieht nicht was im Hintergrund geschieht. Gerade die Callbacks werden so zum Risiko, mit dem jedes Framework anders umgeht. Angular nutzt einen sogenannten Preflight bei Cross Domain aufrufen.

Wenn ein Ajax Callback zu einer anderen Domain zeigt, als der HTML Source Code geladen wurde, spricht man vom einem Cross Domain Request, kurz CORS (Cross Origin Request). Auf das Thema bin ich gestoßen, als ich in einem AngularJS Training einen externen northwind Odata REST Service aufrufen wollte. Nachdem der REST Service einen Fehler liefert, zeigt der Netzwerk Trace statt dem erwarteten POST oder PUT HTTP Kommando im Fiddler einen OPTION Request.

Auf Recherche findet sich, das dieser Request ein W3C Standard (Empfehlung) ist. Der Web Service hat damit die Chance, einen Request abzulehnen, wenn ein Set von Bedingungen nicht erfüllt ist. Man nennt diesen OPTIONS Request preflight.

options1

Da der Odata Developer Service kein CORS unterstützt, wird ein eigener REST Service auf Azure deployed. Aber auch ASP.NET Web Api muss erst für CORS vorbereitet werden. Das notwendige Nuget Paket ist Microsoft.AspNet.WebApi.Cors

options2

In der Startup Logik (hier WebapiConfig.vb) wird Cors aktiviert

   1:  Public Sub Register(ByVal config As HttpConfiguration)
   2:          ' Web API configuration and services
   3:          config.EnableCors()

 

Auf jedem Controller oder Controllermethode können per Attribut Cors Regeln definiert werden.

  • Origin-DNS Herkunft des Callbacks
  • Headers-gültige Header
  • Methods- HTTP Verben durch Komma getrennt

Im Code Beispiel wird durch einen Stern einfach alles erlaubt und damit jede Security ausgehebelt.

   1:   <EnableCors("*", "*", "*")>
   2:      Public Class CustomersController
   3:          Inherits ApiController

Der Aufruf des REST Services durch einen AngularJS $ Resource Call, ruft erst per HTTP GET die Daten ab. Im nächsten Schritt drückt der Benutzer im Dialog auf speichern und sollte damit den HTTP PUT bewirken. Durch den Preflight wird aber zunächst der OPTIONS Aufruf ausgeführt, den unsere Web API nun korrekt beantwortet, so das im dritten Schritt der finale PUT Aufruf erfolgen kann.

options3

Für den Client ist die Information aus dem HTTP Header des OPTIONS Request essentiell. Damit teilt der Service mit, das er für den folgenden PUT auch bereit ist.

options4

Der REST Service ist nun für Test Zugriffe bereit. Wer für Tests diesen nutzen will, das Schema

api / Datenbankname / Customers. http://northwindrest.azurewebsites.net/api/ppedv/customers

Der Datenbankname muss frei gewählt werden und erzeugt eine persönliche Kopie der Northwind Daten, die auch geändert und ergänzt werden kann. Delete ist aktuell nicht implementiert. Auch die anderen Tabellen wie Orders sind (noch) nicht als Controller auscodiert.

Wer  noch mehr zum Thema wissen will, den empfehle ich den MSDN Blog Artikel. Dazu bieten wir einen 2 tägigen ASP.NET Web Api Kurs an.

Kommentare sind geschlossen