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. Neuentwicklung 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, mit dem ein Server die Richtlinie für denselben Ursprung lockern kann. 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 Tutorial erfahren Sie, wie Sie CORS in Ihrer Web-API-Anwendung aktivieren.

Im Tutorial verwendete Software

Einführung

In diesem Tutorial wird die CORS-Unterstützung in ASP.NET-Web-API veranschaulicht. Wir beginnen mit der Erstellung von zwei ASP.NET Projekten– eines namens "WebService", das einen Web-API-Controller hostet, und das andere mit dem Namen "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 Den Webdienst und den Webclient an.

Was ist "gleicher Ursprung"?

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

Diese beiden URLs haben denselben Ursprung:

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

Diese URLs haben andere Ursprünge als die vorherigen beiden:

  • 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 Vergleich 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 für das Kontrollkästchen Web-API .

    Dialogfeld

  3. Fügen Sie einen Web-API-Controller namens TestController mit 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 Tutorial wird die App in Azure App Service Web-Apps bereitgestellt.) Um zu überprüfen, ob die Web-API funktioniert, navigieren Sie zu http://hostname/api/test/, wobei 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. Für dieses Tutorial benötigen Sie keine Authentifizierung.

    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 serviceUrl-Variable 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 "Ausprobieren" klicken, wird eine AJAX-Anforderung mithilfe der im Dropdownfeld aufgeführten 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, erhalten Sie einen Fehler.

Fehler

Hinweis

Wenn Sie den HTTP-Datenverkehr in einem Tool wie Fiddler watch, 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 für denselben 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 zunächst das CORS-NuGet-Paket hinzu. Wählen Sie in Visual Studio im Menü Extras die Option NuGet-Paket-Manager und dann Paket-Manager-Konsole aus. Geben Sie im Fenster Paket-Manager-Konsole 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 Flag, um eine bestimmte Version als Ziel zu verwenden. Das CORS-Paket erfordert die 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 der Klasse das TestControllerAttribut [EnableCors] 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 Origins-Parameter den URI, an dem Sie die WebClient-Anwendung bereitgestellt haben. Dies ermöglicht ursprungsübergreifende Anforderungen von WebClient, während alle anderen domänenübergreifenden Anforderungen weiterhin nicht zulässig sind. Später werde ich die Parameter für [EnableCors] ausführlicher beschreiben.

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

Stellen Sie die aktualisierte WebService-Anwendung erneut bereit. 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 Attribut [EnableCors] richtig konfigurieren und Probleme beheben 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 in Ihrem JavaScript-Code nichts Besonderes tun.

Hier sehen Sie 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, wird der Access-Control-Allow-Origin-Header festgelegt. Der Wert dieses Headers stimmt entweder mit dem Origin-Header überein oder ist der Wildcardwert "*", was bedeutet, dass jeder 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 den Access-Control-Allow-Origin-Header nicht 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 er die tatsächliche Anforderung für die Ressource sendet.

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 anderen Anforderungsheader als Accept, Accept-Language, Content-Language, Content-Type oder Last-Event-ID fest.

  • Der Content-Type-Header (falls festgelegt) ist einer der folgenden:

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

Die Regel über Anforderungsheader 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 Header, die der Browser festlegen kann, z. B. User-Agent, Host oder Content-Length.

Hier sehen Sie 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 Header:

  • Access-Control-Request-Method: Die HTTP-Methode, die für die tatsächliche 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 sehen Sie eine Beispielantwort, wobei vorausgesetzt wird, dass der Server die Anforderung zulässt:

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 auflistet, und optional einen Access-Control-Allow-Headers-Header, in dem die zulässigen Header aufgelistet sind. 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 Preflight OPTIONS-Anforderungen (z. B . Fiddler und Postman) verwendet werden, senden standardmäßig nicht die erforderlichen OPTIONS-Header. Vergewissern Sie sich, dass die Access-Control-Request-Method Header und Access-Control-Request-Headers mit 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 empfangen und verarbeiten kann, fügen Sie der web.config-Datei der App im <system.webServer><handlers> Abschnitt die folgende Konfiguration 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 von OPTIONSVerbHandler verhindert, dass IIS OPTIONS-Anforderungen verarbeitet. Durch das Ersetzen von ExtensionlessUrlHandler-Integrated-4.0 können OPTIONS-Anforderungen die App erreichen, 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 dies für alle Aktionen auf dem Controller. Um CORS für eine Aktion zu deaktivieren, fügen Sie der Aktion das Attribut [DisableCors] hinzu. Im folgenden Beispiel wird CORS für jede Methode mit Ausnahme PutItemvon aktiviert.

[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 ein EnableCorsAttribute-instance 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 Rangfolge:

  1. Action
  2. Controller
  3. Global

Festlegen der zulässigen Ursprünge

Der Origins-Parameter des Attributs [EnableCors] 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 Platzhalterwert "*" verwenden, um Anforderungen aus beliebigen Ursprüngen zuzulassen.

Überlegen Sie sorgfältig, bevor Sie Anforderungen aus einem beliebigen Ursprung 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 methoden-Parameter des Attributs [EnableCors] gibt an, welche HTTP-Methoden auf die Ressource zugreifen dürfen. Um alle Methoden zuzulassen, verwenden Sie den Platzhalterwert "*". Das folgende Beispiel lässt nur GET- und POST-Anforderungen zu.

[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 weiter oben beschrieben, wie eine Preflight-Anforderung einen Access-Control-Request-Headers-Header enthalten kann, der die von der Anwendung festgelegten HTTP-Header auflistet (die sogenannten "Autorenanforderungsheader"). Der Headerparameter des Attributs [EnableCors] gibt an, welche Autorenanforderungsheader zulässig sind. Um Header zuzulassen, legen Sie Header auf "*" fest. Um bestimmte Header zuzulassen, legen Sie Header auf eine durch Trennzeichen getrennte Liste der zulässigen Header fest:

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

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

Wenn Sie Kopfzeilen auf etwas anderes als "*" festlegen, sollten Sie mindestens "accept", "content-type" und "origin" sowie alle benutzerdefinierten Header 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
  • Content-Type
  • 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 Methode des Get Controllers einen benutzerdefinierten Header mit dem Namen "X-Custom-Header" fest. Standardmäßig macht der Browser diesen Header nicht in einer ursprungsübergreifenden Anforderung verfügbar. Um den Header verfügbar zu machen, fügen 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

Anmeldeinformationen erfordern eine spezielle Behandlung in einer CORS-Anforderung. Standardmäßig sendet der Browser keine Anmeldeinformationen mit einer ursprungsübergreifenden Anforderung. Anmeldeinformationen umfassen Cookies sowie HTTP-Authentifizierungsschemas. Zum Senden von Anmeldeinformationen mit einer ursprungsübergreifenden Anforderung muss der Client XMLHttpRequest.withCredentials auf true festlegen.

Direkte Verwendung von XMLHttpRequest :

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 für das 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, die Antwort aber keinen gültigen Access-Control-Allow-Credentials-Header enthält, macht der Browser die Antwort für die Anwendung nicht verfügbar, und die AJAX-Anforderung schlägt fehl.

Achten Sie darauf, SupportsCredentials auf true festzulegen, 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 dies weiß. Die CORS-Spezifikation besagt auch, dass das Festlegen von Ursprüngen auf "*" ungültig ist, wenn SupportsCredentials true ist.

Benutzerdefinierte CORS-Richtlinienanbieter

Das Attribut [EnableCors] implementiert die ICorsPolicyProvider-Schnittstelle . Sie können Ihre 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 kann 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 ICorsPolicyProviderFactory festzulegen, rufen Sie die Erweiterungsmethode SetCorsPolicyProviderFactory 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 unterstützen die aktuellen Versionen aller gängigen Browser CORS.