Sisk

Aktivieren von CORS (Cross-Origin Resource Sharing) in Sisk

Diese Seite wurde automatisch aus dem Englischen übersetzt. Original lesen

Sisk verfügt über ein Werkzeug, das beim Umgang mit Cross-Origin Resource Sharing (CORS) nützlich sein kann, wenn Sie Ihren Dienst öffentlich bereitstellen. Diese Funktion ist kein Teil des HTTP‑Protokolls, sondern ein spezifisches Merkmal von Webbrowsern, definiert vom W3C. Dieser Sicherheitsmechanismus verhindert, dass eine Webseite Anfragen an eine andere Domain stellt als die, von der die Seite bereitgestellt wurde. Ein Dienstanbieter kann bestimmten Domains den Zugriff auf seine Ressourcen erlauben, oder nur einer.

Gleiche Herkunft #

Um eine Ressource als „gleiche Herkunft“ zu identifizieren, muss eine Anfrage den Origin-Header in ihrer Anfrage angeben:

HTTP
GET /api/users HTTP/1.1
Host: example.com
Origin: http://example.com
...

Und der entfernte Server muss mit einem Access-Control-Allow-Origin-Header antworten, der denselben Wert wie die angeforderte Herkunft enthält:

HTTP
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
...

Diese Überprüfung ist explizit: Host, Port und Protokoll müssen mit der Anfrage übereinstimmen. Betrachten Sie das Beispiel:

  • Ein Server gibt zurück, dass sein Access-Control-Allow-Origin https://example.com ist:
    • https://example.net – die Domain ist unterschiedlich.
    • http://example.com – das Schema ist unterschiedlich.
    • http://example.com:5555 – der Port ist unterschiedlich.
    • https://www.example.com – der Host ist unterschiedlich.

In der Spezifikation ist nur die Syntax für beide Header zulässig, sowohl für Anfragen als auch für Antworten. Der URL‑Pfad wird ignoriert. Der Port wird ebenfalls weggelassen, wenn er ein Standardport ist (80 für HTTP und 443 für HTTPS).

HTTP
Origin: null
Origin: <scheme>://<hostname>
Origin: <scheme>://<hostname>:<port>

CORS aktivieren #

Standardmäßig steht Ihnen das Objekt CrossOriginResourceSharingHeaders innerhalb Ihres ListeningHost zur Verfügung.

Sie können CORS beim Initialisieren des Servers konfigurieren:

C#
static async Task Main(string[] args)
{
    using var app = HttpServer.CreateBuilder()
        .UseCors(new CrossOriginResourceSharingHeaders(
            allowOrigin: "http://example.com",
            allowHeaders: ["Authorization"],
            exposeHeaders: ["Content-Type"]))
        .Build();

    await app.StartAsync();
}

Der obige Code sendet die folgenden Header für alle Antworten:

HTTP
HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://example.com
Access-Control-Allow-Headers: Authorization
Access-Control-Expose-Headers: Content-Type

Diese Header müssen für alle Antworten an einen Web‑Client gesendet werden, einschließlich Fehlermeldungen und Weiterleitungen.

Sie werden feststellen, dass die Klasse CrossOriginResourceSharingHeaders zwei ähnliche Eigenschaften besitzt: AllowOrigin und AllowOrigins. Beachten Sie, dass die eine im Plural, die andere im Singular steht.

  • Die AllowOrigin‑Eigenschaft ist statisch: Nur die von Ihnen angegebene Herkunft wird für alle Antworten gesendet.
  • Die AllowOrigins‑Eigenschaft ist dynamisch: Der Server prüft, ob die Herkunft der Anfrage in dieser Liste enthalten ist. Wird sie gefunden, wird sie für die Antwort dieser Herkunft gesendet.

Wenn die erlaubte Herkunft von der Anfrage abhängt, also wenn Sie AllowOrigins oder den unten beschriebenen AutoAllowOrigin-Wert verwenden, sendet Sisk zusätzlich den Header Vary: Origin, damit Caches keine Antwort für eine andere Herkunft wiederverwenden.

Platzhalter und automatische Header #

Alternativ können Sie ein Platzhalterzeichen (*) in der Herkunft der Antwort verwenden, um anzugeben, dass jede Herkunft Zugriff auf die Ressource hat. Dieser Wert ist jedoch für Anfragen mit Anmeldeinformationen (Autorisation‑Header) nicht zulässig und diese Operation führt zu einem Fehler.

Sie können dieses Problem umgehen, indem Sie explizit auflisten, welche Herkünfte über die AllowOrigins‑Eigenschaft erlaubt werden, oder indem Sie die Konstante AutoAllowOrigin im Wert von AllowOrigin verwenden. Diese magische Eigenschaft definiert den Access-Control-Allow-Origin‑Header mit demselben Wert wie der Origin‑Header der Anfrage.

Sie können außerdem AutoFromRequestMethod und AutoFromRequestHeaders für ein Verhalten ähnlich wie AllowOrigin verwenden, das automatisch basierend auf den gesendeten Headern antwortet.

C#
using var host = HttpServer.CreateBuilder()
    .UseCors(new CrossOriginResourceSharingHeaders(
        
        // Antwortet basierend auf dem Origin-Header der Anfrage
        allowOrigin: CrossOriginResourceSharingHeaders.AutoAllowOrigin,
        
        // Antwortet basierend auf dem Access-Control-Request-Method-Header oder der Anfragemethode
        allowMethods: [CrossOriginResourceSharingHeaders.AutoFromRequestMethod],

        // Antwortet basierend auf dem Access-Control-Request-Headers-Header oder den gesendeten Headern
        allowHeaders: [CrossOriginResourceSharingHeaders.AutoFromRequestHeaders],

        exposeHeaders: [HttpKnownHeaderNames.ContentType, "X-Authenticated-Account-Id"],
        allowCredentials: true))
    .Build();

Weitere Möglichkeiten, CORS anzuwenden #

Wenn Sie mit service providers arbeiten, können Sie Werte, die in der Konfigurationsdatei definiert sind, überschreiben:

C#
static async Task Main(string[] args)
{
    using var app = HttpServer.CreateBuilder()
        .UsePortableConfiguration(...)
        .UseCors(cors => {
            // Überschreibt den in der Konfiguration definierten Ursprung
            // Datei.
            cors.AllowOrigin = "http://example.com";
        })
        .Build();

    await app.StartAsync();
}

Deaktivieren von CORS für bestimmte Routen #

C#
[RoutePrefix("api/widgets")]
public class WidgetController : Controller {

    // GET /api/widgets/colors
    [RouteGet("/colors", UseCors = false)]
    public IEnumerable<string> GetWidgets() {
        return new[] { "Green widget", "Red widget" };
    }
}

Werte in der Antwort ersetzen #

Sie können Werte in einer Router‑Aktion explizit ersetzen oder entfernen:

C#
[RoutePrefix("api/widgets")]
public class WidgetController : Controller {

    public IEnumerable<string> GetWidgets(HttpRequest request) {

        // Entfernt den Access-Control-Allow-Credentials-Header
        request.Context.OverrideHeaders.AccessControlAllowCredentials = string.Empty;
        
        // Ersetzt den Access-Control-Allow-Origin-Header
        request.Context.OverrideHeaders.AccessControlAllowOrigin = "https://contorso.com";

        return new[] { "Green widget", "Red widget" };
    }
}

Preflight-Anfragen #

Eine Preflight‑Anfrage ist eine OPTIONS-Methoden‑Anfrage, die der Client vor der eigentlichen Anfrage sendet.

Wenn eine Anfrage mit der Methode OPTIONS dem Pfad einer Route entspricht, aber keine Route explizit für OPTIONS konfiguriert ist, antwortet der Sisk‑Server mit einem 200 OK und den zutreffenden CORS‑Headern, woraufhin der Client mit der eigentlichen Anfrage fortfahren kann.

  • Wenn eine Route explizit mit RouteMethod.Options gemappt ist, zum Beispiel mit MapOptions, verarbeitet diese Route die Anfrage anstelle der automatischen Antwort.
  • Wenn die Route, die dem Pfad entspricht, UseCors = false hat, wird die automatische Antwort weiterhin gesendet, jedoch ohne CORS‑Header.

Hinweis

Vor Sisk 1.7 enthielt die automatische Preflight‑Antwort stets die CORS‑Header, selbst für Routen mit UseCors = false.

CORS global deaktivieren #

Dies ist nicht möglich. Um CORS nicht zu verwenden, konfigurieren Sie es einfach nicht.

Tippen, um die Dokumentation und die API-Referenz zu durchsuchen.