Aktivieren von ursprungsübergreifenden Anforderungen in ASP.NET-Web-API 2

Von Mike Wasson

Dieser Inhalt gilt für eine frühere Version von .NET. Neue Entwicklung sollte ASP.NET Core verwenden. Weitere Informationen zur Verwendung von Web-API und Cross-Origin Requests (CORS) in ASP.NET Core finden Sie unter:

Die Browsersicherheit verhindert, dass eine Webseite AJAX-Anforderungen an eine andere Domäne richtet. Diese Einschränkung wird als Richtlinie des gleichen Ursprungs bezeichnet und verhindert, dass eine schädliche Website sensible Daten von einer anderen Website liest. Manchmal sollen andere Websites jedoch unter Umständen Ihre Web-API aufrufen können.

Cross Origin Resource Sharing (CORS) ist ein W3C-Standard, der es einem Server ermöglicht, die Richtlinie desselben Ursprungs zu entspannen. Mit CORS kann ein Server explizit einige ursprungsübergreifende Anforderungen zulassen und andere ablehnen. CORS ist sicherer und flexibler als frühere Techniken wie JSONP. In diesem Lernprogramm wird gezeigt, wie Sie CORS in Ihrer Webanwendung aktivieren.

Im Lernprogramm verwendete Software

Einführung

In diesem Lernprogramm wird die CORS-Unterstützung in ASP.NET-Web-API veranschaulicht. Wir beginnen mit der Erstellung von zwei ASP.NET Projekten– einem namens "WebService", der einen Web-API-Controller hostt, und der andere namens "WebClient", der WebService aufruft. Da die beiden Anwendungen in unterschiedlichen Domänen gehostet werden, ist eine AJAX-Anforderung von WebClient zu WebService eine ursprungsübergreifende Anforderung.

Zeigt Webdienst und Webclient an

Was ist "gleicher Ursprung"?

Zwei URLs haben denselben Ursprung, wenn sie identische Schemas, Hosts und Ports haben. (RFC 6454)

Diese beiden URLs haben den gleichen Ursprung:

  • http://example.com/foo.html
  • http://example.com/bar.html

Diese URLs haben jeweils einen anderen Ursprung als die beiden vorstehenden:

  • http://example.net - Andere Domäne
  • http://example.com:9000/foo.html - Anderer Port
  • https://example.com/foo.html - Anderes Schema
  • http://www.example.com/foo.html - Andere Unterdomäne

Hinweis

Internet Explorer berücksichtigt den Port beim Vergleichen von Ursprüngen nicht.

Erstellen des WebService-Projekts

Hinweis

In diesem Abschnitt wird davon ausgegangen, dass Sie bereits wissen, wie Web-API-Projekte erstellt werden. Wenn nicht, lesen Sie "Erste Schritte mit ASP.NET-Web-API".

  1. Starten Sie Visual Studio, und erstellen Sie ein neues ASP.NET Webanwendungsprojekt (.NET Framework).

  2. Wählen Sie im Dialogfeld "Neue ASP.NET Webanwendung " die Projektvorlage "Leer " aus. Aktivieren Sie unter "Ordner und Kernverweise hinzufügen" das Kontrollkästchen "Web-API" .

    Dialogfeld

  3. Fügen Sie einen Web-API-Controller mit TestController dem folgenden Code hinzu:

    using System.Net.Http;
    using System.Web.Http;
    
    namespace WebService.Controllers
    {
        public class TestController : ApiController
        {
            public HttpResponseMessage Get()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("GET: Test message")
                };
            }
    
            public HttpResponseMessage Post()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("POST: Test message")
                };
            }
    
            public HttpResponseMessage Put()
            {
                return new HttpResponseMessage()
                {
                    Content = new StringContent("PUT: Test message")
                };
            }
        }
    }
    
  4. Sie können die Anwendung lokal ausführen oder in Azure bereitstellen. (Für die Screenshots in diesem Lernprogramm wird die App für Azure-App Service Web-Apps bereitgestellt.) Um zu überprüfen, ob die Web-API funktioniert, navigieren Sie zu http://hostname/api/test/, zu der Hostname die Domäne ist, in der Sie die Anwendung bereitgestellt haben. Der Antworttext "GET: Test Message" sollte angezeigt werden.

    Webbrowser mit Testmeldung

Erstellen des WebClient-Projekts

  1. Erstellen Sie ein weiteres ASP.NET Webanwendungsprojekt (.NET Framework), und wählen Sie die MVC-Projektvorlage aus. Wählen Sie optional "Authentifizierung ohne Authentifizierung> ändern" aus. Sie benötigen keine Authentifizierung für dieses Lernprogramm.

    MVC-Vorlage im Dialogfeld

  2. Öffnen Sie in Projektmappen-Explorer die Datei "Views/Home/Index.cshtml". Ersetzen Sie den Code in dieser Datei durch Folgendes:

    <div>
        <select id="method">
            <option value="get">GET</option>
            <option value="post">POST</option>
            <option value="put">PUT</option>
        </select>
        <input type="button" value="Try it" onclick="sendRequest()" />
        <span id='value1'>(Result)</span>
    </div>
    
    @section scripts {
    <script>
        // TODO: Replace with the URL of your WebService app
        var serviceUrl = 'http://mywebservice/api/test'; 
    
        function sendRequest() {
            var method = $('#method').val();
    
            $.ajax({
                type: method,
                url: serviceUrl
            }).done(function (data) {
                $('#value1').text(data);
            }).fail(function (jqXHR, textStatus, errorThrown) {
                $('#value1').text(jqXHR.responseText || textStatus);
            });
        }
    </script>
    }
    

    Verwenden Sie für die variable serviceUrl den URI der WebService-App.

  3. Führen Sie die WebClient-App lokal aus, oder veröffentlichen Sie sie auf einer anderen Website.

Wenn Sie auf die Schaltfläche "Testen" klicken, wird eine AJAX-Anforderung mithilfe der im Dropdownfeld aufgelisteten HTTP-Methode (GET, POST oder PUT) an die WebService-App übermittelt. Auf diese Weise können Sie verschiedene ursprungsübergreifende Anforderungen untersuchen. Derzeit unterstützt die WebService-App CORS nicht. Wenn Sie also auf die Schaltfläche klicken, wird eine Fehlermeldung angezeigt.

Fehler

Hinweis

Wenn Sie den HTTP-Datenverkehr in einem Tool wie Fiddler beobachten, sehen Sie, dass der Browser die GET-Anforderung sendet und die Anforderung erfolgreich ist, aber der AJAX-Aufruf gibt einen Fehler zurück. Es ist wichtig zu verstehen, dass die Richtlinie mit demselben Ursprung nicht verhindert, dass der Browser die Anforderung sendet . Stattdessen wird verhindert, dass die Anwendung die Antwort sieht.

Fiddler-Webdebugger mit Webanforderungen

Aktivieren von CORS

Jetzt aktivieren wir CORS in der WebService-App. Fügen Sie zuerst das CORS NuGet-Paket hinzu. Wählen Sie in Visual Studio im Menü "Extras" "NuGet Paket-Manager" und dann Paket-Manager Konsole aus. Geben Sie im Paket-Manager Konsolenfenster den folgenden Befehl ein:

Install-Package Microsoft.AspNet.WebApi.Cors

Dieser Befehl installiert das neueste Paket und aktualisiert alle Abhängigkeiten, einschließlich der wichtigsten Web-API-Bibliotheken. Verwenden Sie das -Version Kennzeichen, um auf eine bestimmte Version zu abzielen. Das CORS-Paket erfordert Web-API 2.0 oder höher.

Öffnen Sie die Datei App_Start/WebApiConfig.cs. Fügen Sie der WebApiConfig.Register-Methode den folgenden Code hinzu:

using System.Web.Http;
namespace WebService
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // New code
            config.EnableCors();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
}

Fügen Sie als Nächstes das Attribut [EnableCors] zur TestController Klasse hinzu:

using System.Net.Http;
using System.Web.Http;
using System.Web.Http.Cors;

namespace WebService.Controllers
{
    [EnableCors(origins: "http://mywebclient.azurewebsites.net", headers: "*", methods: "*")]
    public class TestController : ApiController
    {
        // Controller methods not shown...
    }
}

Verwenden Sie für den Ursprüngeparameter den URI, in dem Sie die WebClient-Anwendung bereitgestellt haben. Dies ermöglicht ursprungsübergreifende Anforderungen von WebClient, während alle anderen domänenübergreifenden Anforderungen weiterhin deaktiviert werden. Später werde ich die Parameter für [EnableCors] ausführlicher beschreiben.

Fügen Sie keinen Schrägstrich am Ende der Ursprungs-URL ein.

Erneutes Bereitstellen der aktualisierten WebService-Anwendung. Sie müssen WebClient nicht aktualisieren. Nun sollte die AJAX-Anforderung von WebClient erfolgreich sein. Die METHODEN GET, PUT und POST sind alle zulässig.

Webbrowser mit erfolgreicher Testmeldung

Funktionsweise von CORS

In diesem Abschnitt wird beschrieben, was in einer CORS-Anforderung auf der Ebene der HTTP-Nachrichten geschieht. Es ist wichtig zu verstehen, wie CORS funktioniert, damit Sie das [EnableCors] -Attribut richtig konfigurieren und problembehandlungen können, wenn die Dinge nicht wie erwartet funktionieren.

Die CORS-Spezifikation führt mehrere neue HTTP-Header ein, die ursprungsübergreifende Anforderungen ermöglichen. Wenn ein Browser CORS unterstützt, werden diese Header automatisch für ursprungsübergreifende Anforderungen festgelegt. Sie müssen nichts Besonderes in Ihrem JavaScript-Code tun.

Hier ist ein Beispiel für eine ursprungsübergreifende Anforderung. Der Header "Origin" gibt die Domäne der Website an, die die Anforderung stellt.

GET http://myservice.azurewebsites.net/api/test HTTP/1.1
Referer: http://myclient.azurewebsites.net/
Accept: */*
Accept-Language: en-US
Origin: http://myclient.azurewebsites.net
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net

Wenn der Server die Anforderung zulässt, legt er den Access-Control-Allow-Origin-Header fest. Der Wert dieser Kopfzeile entspricht entweder der Origin-Kopfzeile oder ist der Wildcardwert "*", was bedeutet, dass ein beliebiger Ursprung zulässig ist.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Type: text/plain; charset=utf-8
Access-Control-Allow-Origin: http://myclient.azurewebsites.net
Date: Wed, 05 Jun 2013 06:27:30 GMT
Content-Length: 17

GET: Test message

Wenn die Antwort nicht den Access-Control-Allow-Origin-Header enthält, schlägt die AJAX-Anforderung fehl. Insbesondere lässt der Browser die Anforderung nicht zu. Selbst wenn der Server eine erfolgreiche Antwort zurückgibt, stellt der Browser die Antwort nicht für die Clientanwendung zur Verfügung.

Preflight-Anforderungen

Bei einigen CORS-Anforderungen sendet der Browser eine zusätzliche Anforderung, die als "Preflight-Anforderung" bezeichnet wird, bevor die tatsächliche Anforderung für die Ressource gesendet wird.

Der Browser kann die Preflight-Anforderung überspringen, wenn die folgenden Bedingungen erfüllt sind:

  • Die Anforderungsmethode ist GET, HEAD oder POST und

  • Die Anwendung legt keine Anforderungsheader außer Accept, Accept-Language, Content-Language, Content-Type oder Last-Event-ID fest und

  • Der Inhaltstypheader (sofern festgelegt) ist eine der folgenden:

    • application/x-www-form-urlencoded
    • multipart/form-data
    • text/plain

Die Regel zu Anforderungsheadern gilt für Header, die die Anwendung durch Aufrufen von setRequestHeader für das XMLHttpRequest-Objekt festlegt. (Die CORS-Spezifikation ruft diese "Autorenanforderungsheader" auf.) Die Regel gilt nicht für Kopfzeilen, die der Browser festlegen kann, z. B. Benutzer-Agent, Host oder Inhaltslänge.

Hier ist ein Beispiel für eine Preflight-Anforderung:

OPTIONS http://myservice.azurewebsites.net/api/test HTTP/1.1
Accept: */*
Origin: http://myclient.azurewebsites.net
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: accept, x-my-custom-header
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)
Host: myservice.azurewebsites.net
Content-Length: 0

Die Pre-Flight-Anforderung verwendet die HTTP OPTIONS-Methode. Es enthält zwei spezielle Kopfzeilen:

  • Access-Control-Request-Method: Die HTTP-Methode, die für die eigentliche Anforderung verwendet wird.
  • Access-Control-Request-Headers: Eine Liste der Anforderungsheader, die die Anwendung für die tatsächliche Anforderung festgelegt hat. (Auch hier sind keine Header enthalten, die vom Browser festgelegt werden.)

Hier ist eine Beispielantwort, vorausgesetzt, der Server lässt die Anforderung zu:

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Access-Control-Allow-Origin: http://myclient.azurewebsites.net
Access-Control-Allow-Headers: x-my-custom-header
Access-Control-Allow-Methods: PUT
Date: Wed, 05 Jun 2013 06:33:22 GMT

Die Antwort enthält einen Access-Control-Allow-Methods-Header, der die zulässigen Methoden und optional einen Access-Control-Allow-Headers-Header auflistet, der die zulässigen Kopfzeilen auflistet. Wenn die Preflight-Anforderung erfolgreich ist, sendet der Browser die tatsächliche Anforderung, wie zuvor beschrieben.

Tools, die häufig zum Testen von Endpunkten mit Optionsanforderungen im Preflight verwendet werden, senden standardmäßig nicht die erforderlichen OPTIONS-Header. Vergewissern Sie sich, dass die Access-Control-Request-Method Kopfzeilen mit Access-Control-Request-Headers der Anforderung gesendet werden und dass OPTIONS-Header die App über IIS erreichen.

Um IIS so zu konfigurieren, dass eine ASP.NET-App OPTION-Anforderungen empfängt und verarbeitet, fügen Sie die folgende Konfiguration zur Datei "web.config" der App im <system.webServer><handlers> Abschnitt hinzu:

<system.webServer>
  <handlers>
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
  </handlers>
</system.webServer>

Das Entfernen verhindert, OPTIONSVerbHandler dass IIS OPTIONS-Anforderungen verarbeitet. Durch den Austausch von ExtensionlessUrlHandler-Integrated-4.0 OPTIONS-Anforderungen kann die App erreicht werden, da die Standardmodulregistrierung nur GET-, HEAD-, POST- und DEBUG-Anforderungen mit erweiterungslosen URLs zulässt.

Bereichsregeln für [EnableCors]

Sie können CORS pro Aktion, pro Controller oder global für alle Web-API-Controller in Ihrer Anwendung aktivieren.

Pro Aktion

Um CORS für eine einzelne Aktion zu aktivieren, legen Sie das Attribut [EnableCors] für die Aktionsmethode fest. Im folgenden Beispiel wird CORS nur für die GetItem Methode aktiviert.

public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }

    [EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
    public HttpResponseMessage GetItem(int id) { ... }

    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage PutItem(int id) { ... }
}

Pro Controller

Wenn Sie [EnableCors] für die Controllerklasse festlegen, gilt sie für alle Aktionen auf dem Controller. Um CORS für eine Aktion zu deaktivieren, fügen Sie der Aktion das Attribut [DisableCors] hinzu. Das folgende Beispiel aktiviert CORS für jede Methode außer PutItem.

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "*")]
public class ItemsController : ApiController
{
    public HttpResponseMessage GetAll() { ... }
    public HttpResponseMessage GetItem(int id) { ... }
    public HttpResponseMessage Post() { ... }

    [DisableCors]
    public HttpResponseMessage PutItem(int id) { ... }
}

Global

Um CORS für alle Web-API-Controller in Ihrer Anwendung zu aktivieren, übergeben Sie eine EnableCorsAttribute-Instanz an die EnableCors-Methode :

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var cors = new EnableCorsAttribute("www.example.com", "*", "*");
        config.EnableCors(cors);
        // ...
    }
}

Wenn Sie das Attribut auf mehr als einen Bereich festlegen, lautet die Reihenfolge der Rangfolge:

  1. Aktion
  2. Controller
  3. Global

Festlegen der zulässigen Ursprünge

Der Origin-Parameter des [EnableCors] -Attributs gibt an, welche Ursprünge auf die Ressource zugreifen dürfen. Der Wert ist eine durch Trennzeichen getrennte Liste der zulässigen Ursprünge.

[EnableCors(origins: "http://www.contoso.com,http://www.example.com", 
    headers: "*", methods: "*")]

Sie können auch den Wildcardwert "*" verwenden, um Anforderungen von beliebigen Ursprüngen zuzulassen.

Überlegen Sie sich sorgfältig, bevor Sie Anforderungen von einem beliebigen Ursprung aus zulassen. Dies bedeutet, dass buchstäblich jede Website AJAX-Aufrufe an Ihre Web-API tätigen kann.

// Allow CORS for all origins. (Caution!)
[EnableCors(origins: "*", headers: "*", methods: "*")]

Festlegen der zulässigen HTTP-Methoden

Der Methodenparameter des Attributs [EnableCors] gibt an, welche HTTP-Methoden auf die Ressource zugreifen dürfen. Um alle Methoden zuzulassen, verwenden Sie den Wildcardwert "*". Im folgenden Beispiel werden nur GET- und POST-Anforderungen zulässig.

[EnableCors(origins: "http://www.example.com", headers: "*", methods: "get,post")]
public class TestController : ApiController
{
    public HttpResponseMessage Get() { ... }
    public HttpResponseMessage Post() { ... }
    public HttpResponseMessage Put() { ... }    
}

Festlegen der zulässigen Anforderungsheader

In diesem Artikel wurde beschrieben, wie eine Preflight-Anforderung möglicherweise einen Access-Control-Request-Headers-Header enthält und die von der Anwendung festgelegten HTTP-Header auflistet (die sogenannten "Author Request Headers"). Der Headers-Parameter des [EnableCors]-Attributs gibt an, welche Autorenanforderungsheader zulässig sind. Um Kopfzeilen zuzulassen, legen Sie Kopfzeilen auf "*" fest. Um bestimmte Kopfzeilen zuzulassen, legen Sie Kopfzeilen auf eine durch Trennzeichen getrennte Liste der zulässigen Kopfzeilen fest:

[EnableCors(origins: "http://example.com", 
    headers: "accept,content-type,origin,x-my-header", methods: "*")]

Browser sind jedoch nicht vollständig konsistent bei der Festlegung von Access-Control-Request-Headern. Chrome enthält z. B. derzeit "origin". FireFox enthält keine Standardheader wie "Accept", auch wenn die Anwendung sie im Skript festlegt.

Wenn Sie Kopfzeilen auf "*" festlegen, sollten Sie mindestens "accept", "content-type" und "origin" sowie alle benutzerdefinierten Kopfzeilen einschließen, die Sie unterstützen möchten.

Festlegen der zulässigen Antwortheader

Standardmäßig macht der Browser nicht alle Antwortheader für die Anwendung verfügbar. Standardmäßig sind folgende Antwortheader verfügbar:

  • Cachesteuerung
  • Inhaltssprache
  • Inhaltsart
  • Läuft ab
  • Last-Modified
  • Pragma

Die CORS-Spezifikation ruft diese einfachen Antwortheader auf. Um andere Header für die Anwendung verfügbar zu machen, legen Sie den parameter "exposedHeaders " von [EnableCors] fest.

Im folgenden Beispiel legt die Get Controllermethode einen benutzerdefinierten Header namens "X-Custom-Header" fest. Standardmäßig macht der Browser diesen Header in einer ursprungsübergreifenden Anforderung nicht verfügbar. Um die Kopfzeile verfügbar zu machen, schließen Sie "X-Custom-Header" in exposedHeaders ein.

[EnableCors(origins: "*", headers: "*", methods: "*", exposedHeaders: "X-Custom-Header")]
public class TestController : ApiController
{
    public HttpResponseMessage Get()
    {
        var resp = new HttpResponseMessage()
        {
            Content = new StringContent("GET: Test message")
        };
        resp.Headers.Add("X-Custom-Header", "hello");
        return resp;
    }
}

Übergeben von Anmeldeinformationen in ursprungsübergreifenden Anforderungen

Für Anmeldeinformationen ist in einer CORS-Anforderung eine besondere Behandlung erforderlich. Standardmäßig sendet der Browser keine Anmeldeinformationen mit einer ursprungsübergreifenden Anforderung. Anmeldeinformationen umfassen Cookies sowie HTTP-Authentifizierungsschemas. Um Anmeldeinformationen mit einer ursprungsübergreifenden Anforderung zu senden, muss der Client XMLHttpRequest.withCredentials auf "true" festlegen.

Verwenden von XMLHttpRequest direkt:

var xhr = new XMLHttpRequest();
xhr.open('get', 'http://www.example.com/api/test');
xhr.withCredentials = true;

In jQuery:

$.ajax({
    type: 'get',
    url: 'http://www.example.com/api/test',
    xhrFields: {
        withCredentials: true
    }

Darüber hinaus muss der Server die Anmeldeinformationen zulassen. Um ursprungsübergreifende Anmeldeinformationen in der Web-API zuzulassen, legen Sie die SupportsCredentials-Eigenschaft im Attribut [EnableCors] auf "true" fest:

[EnableCors(origins: "http://myclient.azurewebsites.net", headers: "*", 
    methods: "*", SupportsCredentials = true)]

Wenn diese Eigenschaft "true" ist, enthält die HTTP-Antwort einen Access-Control-Allow-Credentials-Header. Dieser Header teilt dem Browser mit, dass der Server Anmeldeinformationen für eine ursprungsübergreifende Anforderung zulässt.

Wenn der Browser Anmeldeinformationen sendet, aber die Antwort keinen gültigen Access-Control-Allow-Credentials-Header enthält, macht der Browser die Antwort auf die Anwendung nicht verfügbar, und die AJAX-Anforderung schlägt fehl.

Achten Sie beim Festlegen von SupportsCredentials auf "true", da dies bedeutet, dass eine Website in einer anderen Domäne die Anmeldeinformationen eines angemeldeten Benutzers im Namen des Benutzers an Ihre Web-API senden kann, ohne dass der Benutzer sich bewusst ist. Die CORS-Spezifikation gibt auch an, dass das Festlegen von Ursprüngen auf "*" ungültig ist, wenn SupportsCredentials wahr ist.

Benutzerdefinierte CORS-Richtlinienanbieter

Das [EnableCors] -Attribut implementiert die ICorsPolicyProvider-Schnittstelle . Sie können Eine eigene Implementierung bereitstellen, indem Sie eine Klasse erstellen, die von "Attribute" abgeleitet wird und ICorsPolicyProvider implementiert.

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false)]
public class MyCorsPolicyAttribute : Attribute, ICorsPolicyProvider 
{
    private CorsPolicy _policy;

    public MyCorsPolicyAttribute()
    {
        // Create a CORS policy.
        _policy = new CorsPolicy
        {
            AllowAnyMethod = true,
            AllowAnyHeader = true
        };

        // Add allowed origins.
        _policy.Origins.Add("http://myclient.azurewebsites.net");
        _policy.Origins.Add("http://www.contoso.com");
    }

    public Task<CorsPolicy> GetCorsPolicyAsync(HttpRequestMessage request)
    {
        return Task.FromResult(_policy);
    }
}

Jetzt können Sie das Attribut an beliebiger Stelle anwenden, die Sie [EnableCors] platzieren würden.

[MyCorsPolicy]
public class TestController : ApiController
{
    .. //

Beispielsweise könnte ein benutzerdefinierter CORS-Richtlinienanbieter die Einstellungen aus einer Konfigurationsdatei lesen.

Alternativ zur Verwendung von Attributen können Sie ein ICorsPolicyProviderFactory-Objekt registrieren, das ICorsPolicyProvider-Objekte erstellt.

public class CorsPolicyFactory : ICorsPolicyProviderFactory
{
    ICorsPolicyProvider _provider = new MyCorsPolicyProvider();

    public ICorsPolicyProvider GetCorsPolicyProvider(HttpRequestMessage request)
    {
        return _provider;
    }
}

Um die ICorsPolicyProviderFactory festzulegen, rufen Sie die SetCorsPolicyProviderFactory-Erweiterungsmethode beim Start wie folgt auf:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.SetCorsPolicyProviderFactory(new CorsPolicyFactory());
        config.EnableCors();

        // ...
    }
}

Browserunterstützung

Das CorS-Paket der Web-API ist eine serverseitige Technologie. Der Browser des Benutzers muss auch CORS unterstützen. Glücklicherweise enthalten die aktuellen Versionen aller hauptbrowser Unterstützung für CORS.