Freigeben über


Implementierung des Http.sys-Webservers in ASP.NET Core

Hinweis

Dies ist nicht die neueste Version dieses Artikels. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Warnung

Diese Version von ASP.NET Core wird nicht mehr unterstützt. Weitere Informationen finden Sie in der .NET- und .NET Core-Supportrichtlinie. Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Wichtig

Diese Informationen beziehen sich auf ein Vorabversionsprodukt, das vor der kommerziellen Freigabe möglicherweise noch wesentlichen Änderungen unterliegt. Microsoft gibt keine Garantie, weder ausdrücklich noch impliziert, hinsichtlich der hier bereitgestellten Informationen.

Die aktuelle Version finden Sie in der .NET 9-Version dieses Artikels.

Von Tom Dykstra und Chris Ross

HTTP.sys ist ein Webserver für ASP.NET Core, der nur unter Windows ausgeführt werden kann. HTTP.sys stellt eine Alternative zum Kestrel-Server dar und bietet einige Features, die in Kestrel fehlen.

Wichtig

HTTP.sys ist nicht mit dem ASP.NET Core-Modul kompatibel und kann nicht mit IIS oder IIS Express verwendet werden.

HTTP.sys unterstützt die folgenden Features:

  • Windows-Authentifizierung
  • Portfreigabe
  • HTTPS mit SNI
  • HTTP/2 über TLS (Windows 10 oder höher)
  • Direkte Dateiübertragung
  • Zwischenspeichern von Antworten
  • WebSockets (Windows 8 oder höher)

Unterstützte Windows-Versionen:

  • Windows 7 oder höher
  • Windows Server 2008 R2 oder höher

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Empfohlene Verwendung von HTTP.sys

HTTP.sys eignet sich für Bereitstellungen, auf die Folgendes zutrifft:

  • Sie müssen den Server ohne IIS direkt mit dem Internet verbinden.

    HTTP.sys kommuniziert direkt mit dem Internet

  • Eine interne Bereitstellung erfordert ein Feature, das in Kestrel nicht verfügbar ist. Weitere Informationen finden Sie unter Kestrel im Vergleich zu HTTP.sys.

    HTTP.sys kommuniziert direkt mit dem internen Netzwerk

Bei HTTP.sys handelt es sich um eine ausgereifte Technologie, die Schutz vor vielen Arten von Angriffen bietet und zudem die Stabilität, Sicherheit und Skalierbarkeit eines Webservers mit vollem Funktionsumfang bereitstellt. IIS selbst wird auf HTTP.sys als HTTP-Listener ausgeführt.

HTTP/2-Unterstützung

HTTP/2 ist für ASP.NET Core-Apps aktiviert, wenn die folgenden Basisanforderungen erfüllt sind:

  • Windows Server 2016/Windows 10 oder höher
  • ALPN-Verbindung (Application-Layer Protocol Negotiation)
  • TLS 1.2-Verbindung oder höher

Wenn eine HTTP/2-Verbindung hergestellt wurde, meldet HttpRequest.ProtocolHTTP/2.

HTTP/2 ist standardmäßig aktiviert. Für die Verbindung wird ein Fallback auf HTTP/1.1 ausgeführt, wenn keine HTTP/2-Verbindung hergestellt wurde. In einer zukünftigen Version von Windows werden HTTP/2-Konfigurationsflags verfügbar sein, einschließlich der Möglichkeit, HTTP/2 mit HTTP.sys zu deaktivieren.

HTTP/3-Unterstützung

HTTP/3 ist für ASP.NET Core-Apps aktiviert, wenn die folgenden Basisanforderungen erfüllt sind:

Die vorherigen Windows 11-Buildversionen erfordern möglicherweise die Verwendung eines Windows-Insider-Builds.

HTTP/3 wird anhand des Headers alt-svc als Upgrade von HTTP/1.1 oder HTTP/2 erkannt. Das bedeutet, dass die erste Anforderung normalerweise HTTP/1.1 oder HTTP/2 verwendet, bevor der Wechsel zu HTTP/3 erfolgt. Http.Sys fügt den alt-svc-Header nicht automatisch hinzu, er muss von der Anwendung hinzugefügt werden. Der folgende Code ist ein Middlewarebeispiel, das den alt-svc-Antwortheader hinzufügt.

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

Platzieren Sie den vorangehenden Code frühzeitig in der Anforderungspipeline.

Http.Sys unterstützt auch das Senden einer ALTSVC-HTTP/2-Protokollnachricht statt eines Antwortheaders, um den Client zu benachrichtigen, dass HTTP/3 verfügbar ist. Siehe dazu den EnableAltSvc-Registrierungsschlüssel. Dazu werden netsh sslcert-Bindungen benötigt, die anstelle von IP-Adressen Hostnamen verwenden.

Kernelmodusauthentifizierung mit Kerberos

HTTP.sys delegiert zur Kernelmodusauthentifizierung mit dem Kerberos-Authentifizierungsprotokoll. Die Benutzermodusauthentifizierung wird nicht von Kerberos und HTTP.sys unterstützt. Das Computerkonto muss zum Entschlüsseln des Kerberos-Tokens/-Tickets verwendet werden, das von Active Directory abgerufen und zur Authentifizierung des Benutzers vom Client an den Server weitergeleitet wird. Registrieren Sie den Dienstprinzipalnamen (SPN) für den Host, nicht für den Benutzer der App.

Unterstützung für Kernelmodus-Antwortpufferung

In einigen Szenarien können hohe Mengen kleiner Schreibvorgänge mit hoher Latenz zu erheblichen Leistungseinbußen für HTTP.sys führen. Diese Auswirkung ist auf das Fehlen eines Pipe-Puffers in der HTTP.sys-Implementierung zurückzuführen. Um die Leistung in diesen Szenarien zu verbessern, ist die Unterstützung für Antwortpuffer in HTTP.sys enthalten. Aktivieren Sie die Pufferung, indem Sie HttpSysOptions.EnableKernelResponseBuffering auf true festlegen.

Die Antwortpufferung sollte von einer App aktiviert werden, die synchrone E/A- oder asynchrone E/A-Vorgänge mit jeweils nicht mehr als einem ausstehenden Schreibvorgang ausführt. In diesen Szenarien kann die Antwortpufferung den Durchsatz gegenüber Verbindungen mit hoher Latenz erheblich verbessern.

Apps, die asynchrone E/A-Vorgänge verwenden und bei denen möglicherweise mehrere Schreibvorgänge gleichzeitig ausstehen, sollten dieses Flag nicht verwenden. Das Aktivieren dieses Flags kann zu einer höheren CPU- und Arbeitsspeicherauslastung durch HTTP.Sys führen.

Empfohlene Verwendung von HTTP.sys

Konfigurieren der ASP.NET Core-App für die Verwendung von HTTP.sys

Rufen Sie die Erweiterungsmethode UseHttpSys auf, wenn Sie den Host erstellen, und geben Sie dabei alle erforderlichen HttpSysOptions-Objekte an. Im folgenden Beispiel werden Optionen auf ihre Standardwerte festgelegt:

using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Hosting.Server.Features;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys(options =>
{
    options.AllowSynchronousIO = false;
    options.Authentication.Schemes = AuthenticationSchemes.None;
    options.Authentication.AllowAnonymous = true;
    options.MaxConnections = null;
    options.MaxRequestBodySize = 30_000_000;
    options.UrlPrefixes.Add("http://localhost:5005");
});

builder.Services.AddRazorPages();

var app = builder.Build();

Die weitere Konfiguration von HTTP.sys erfolgt über Registrierungseinstellungen.

Weitere Informationen zu den HTTP.sys-Optionen finden Sie unter HttpSysOptions.

MaxRequestBodySize

Die maximal zulässige Größe eines Anforderungstexts in Bytes. Wenn dieser Wert auf null festgelegt wird, ist die maximale Größe für Anforderungstexte unbegrenzt. Dieser Grenzwert wirkt sich nicht auf Verbindungen aus, für die ein Upgrade durchgeführt wurde – diese sind immer unbegrenzt.

Die empfohlene Methode zum Überschreiben des Grenzwerts in einer ASP.NET Core-MVC-App für ein einzelnes IActionResult besteht im Verwenden von RequestSizeLimitAttribute in einer Aktionsmethode:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Eine Ausnahme wird ausgelöst, wenn die App versucht, den Grenzwert einer Anforderung zu konfigurieren, nachdem die App bereits mit dem Lesen der Anforderung begonnen hat. Sie können eine IsReadOnly-Eigenschaft verwenden, um darauf hinzuweisen, dass sich die MaxRequestBodySize-Eigenschaft im schreibgeschützten Zustand befindet, der Grenzwert also nicht mehr konfiguriert werden kann.

Wenn die App MaxRequestBodySize pro Anforderung außer Kraft setzen sollte, verwenden Sie das IHttpMaxRequestBodySizeFeature:

app.Use((context, next) =>
{
    context.Features.GetRequiredFeature<IHttpMaxRequestBodySizeFeature>()
                                             .MaxRequestBodySize = 10 * 1024;

    var server = context.RequestServices
        .GetRequiredService<IServer>();
    var serverAddressesFeature = server.Features
                                 .GetRequiredFeature<IServerAddressesFeature>();

    var addresses = string.Join(", ", serverAddressesFeature.Addresses);

    var loggerFactory = context.RequestServices
        .GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    logger.LogInformation("Addresses: {addresses}", addresses);

    return next(context);
});

Wenn Sie Visual Studio verwenden, stellen Sie sicher, dass die App nicht für die Ausführung von IIS oder IIS Express konfiguriert ist.

In Visual Studio ist das Standardstartprofil auf IIS Express ausgerichtet. Wenn das Projekt als Konsolen-App ausgeführt werden soll, ändern Sie das ausgewählte Profil manuell, wie im folgenden Screenshot dargestellt:

Auswählen des Profils der App-Konsole

Konfigurieren von Windows Server

  1. Bestimmen Sie die Ports, die für die App geöffnet werden sollen, und verwenden Sie die Windows-Firewall oder das PowerShell-Cmdlet New-NetFirewallRule, um Firewall-Ports zu öffnen, damit der Datenverkehr HTTP.sys erreichen kann. In den folgenden Befehlen und der Appkonfiguration wird Port 443 verwendet.

  2. Öffnen Sie bei der Bereitstellung für eine Azure-VM die Ports in der Netzwerksicherheitsgruppe. In den folgenden Befehlen und der Appkonfiguration wird Port 443 verwendet.

  3. Beziehen Sie X.509-Zertifikate und installieren Sie sie, falls erforderlich.

    Erstellen Sie unter Windows selbstsignierte Zertifikate mit dem PowerShell-Cmdlet „New-SelfSignedCertificate“. Ein nicht unterstütztes Beispiel finden Sie unter UpdateIISExpressSSLForChrome.ps1.

    Installieren Sie entweder selbstsignierte oder CA-signierte Zertifikate im Speicher Lokaler Server>Persönlich des Servers.

  4. Wenn es sich bei der App um eine frameworkabhängige Bereitstellung handelt, installieren Sie .NET Core, .NET Framework oder beides (wenn es sich um eine .NET Core-App für das .NET Framework handelt).

    • .NET Core: Wenn die App .NET Core erfordert, rufen Sie den Installer für die .NET Core Runtime über .NET Core-Downloads ab, und führen Sie ihn aus. Installieren Sie nicht das vollständige SDK auf dem Server.
    • .NET Framework: Erfordert die App .NET Framework, rufen Sie das .NET Framework-Installationshandbuch auf. Installieren Sie das erforderliche .NET Framework. Der Installer für das neueste .NET Framework steht auf der Seite .NET Core-Downloads zur Verfügung.

    Wenn die App eine eigenständige Bereitstellung ist, enthält die App die Runtime in ihrer Bereitstellung. Es ist keine Frameworkinstallation auf dem Server erforderlich.

  5. Konfigurieren Sie URLs und Ports in der App.

    Standardmäßig ist ASP.NET Core an http://localhost:5000 gebunden. Zum Konfigurieren von URL-Präfixen und Ports stehen folgende Optionen zur Verfügung:

    Das folgende Codebeispiel zeigt, wie Sie UrlPrefixes mit der lokalen IP-Adresse 10.0.0.4 des Servers auf Port 443 verwenden:

    var builder = WebApplication.CreateBuilder(args);
    
    builder.WebHost.UseHttpSys(options =>
    {
        options.UrlPrefixes.Add("https://10.0.0.4:443");
    });
    
    builder.Services.AddRazorPages();
    
    var app = builder.Build();
    

    Ein Vorteil von UrlPrefixes besteht darin, dass bei falsch formatierten Präfixen sofort eine Fehlermeldung generiert wird.

    Die Einstellungen in UrlPrefixes überschreiben die Einstellungen für UseUrls/urls/ASPNETCORE_URLS. Daher bieten UseUrls, urls und die Umgebungsvariable ASPNETCORE_URLS den Vorteil, dass sie den Wechsel zwischen Kestrel und HTTP.sys vereinfachen.

    HTTP.sys erkennt zwei Arten von Platzhaltern in URL-Präfixen:

    • * ist eine schwache Bindung, auch bekannt als Fallbackbindung. Wenn das URL-Präfix http://*:5000 lautet und etwas anderes an Port 5000 gebunden ist, wird diese Bindung nicht verwendet.
    • + ist eine starke Bindung. Wenn das URL-Präfix http://+:5000 lautet, wird diese Bindung vor anderen Port 5000-Bindungen verwendet.

    Weitere Informationen finden Sie unter UrlPrefix-Zeichenfolgen.

    Warnung

    Allgemeine Platzhalterbindungen (http://*:80/ und http://+:80) dürfen nicht verwendet werden. Platzhalterbindungen auf oberster Ebene gefährden die Sicherheit Ihrer App. Dies gilt für starke und schwache Platzhalter. Verwenden Sie statt Platzhaltern explizite Hostnamen oder IP-Adressen. Platzhalterbindungen in untergeordneten Domänen (z.B. *.mysub.com) stellen kein Sicherheitsrisiko dar, wenn Sie die gesamte übergeordnete Domäne steuern (im Gegensatz zu *.com, das angreifbar ist). Weitere Informationen finden Sie unter RFC 9110: Abschnitt 7.2. Host und :authority.

    Apps und Container erhalten häufig nur einen Port, dem sie lauschen können, z. B. Port 80, und keine zusätzlichen Einschränkungen für den Host oder Pfad. HTTP_PORTS und HTTPS_PORTS sind Konfigurationsschlüssel, die die Lauschports für Kestrel- und HTTP.sys-Server angeben. Diese Schlüssel können als Umgebungsvariablen, die mit den Präfixen DOTNET_ oder ASPNETCORE_ definiert sind, oder direkt über andere Konfigurationseingaben wie appsettings.json angegeben werden. Jede ist eine durch Semikolons getrennte Liste mit Portwerten. Dies wird im folgenden Beispiel veranschaulicht:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Das obige Beispiel ist eine Kurzform der folgenden Konfiguration, die das Schema (HTTP oder HTTPS) und alle Hosts oder IP-Adressen angibt.

    ASPNETCORE_URLS=http://*:80/;http://*:8080/;https://*:443/;https://*:8081/
    

    Die Konfigurationsschlüssel HTTP_PORTS und HTTPS_PORTS haben eine niedrigere Priorität und werden von URLs oder Werten überschrieben, die direkt im Code angegeben werden. Zertifikate müssen weiterhin separat über serverspezifische Mechanismen für HTTPS konfiguriert werden.

    Diese Konfigurationsschlüssel entsprechen den Platzhalterbindungen auf oberster Ebene. Sie sind für Entwicklungs- und Containerszenarios praktisch. Vermeiden Sie Platzhalter jedoch bei der Ausführung auf einem Computer, der möglicherweise auch andere Dienste hostet.

  6. URL-Präfixe können vorab auf dem Server registriert werden.

    Das integrierte Tool für die Konfiguration von HTTP.sys ist netsh.exe. Mithilfe von netsh.exe können Sie URL-Präfixe reservieren und X.509-Zertifikate zuweisen. Das Tool erfordert Administratorrechte.

    Verwenden Sie das Tool netsh.exe, um die URLs für die App zu registrieren:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: Der vollqualifizierte Uniform Resource Locator (URL). Verwenden Sie keine Platzhalterbindung. Verwenden Sie einen gültigen Hostnamen oder eine gültige lokale IP-Adresse. Die URL muss einen nachgestellten Schrägstrich enthalten.
    • <USER>: gibt den Benutzer oder den Benutzergruppennamen an

    Im folgenden Beispiel ist die lokale IP-Adresse des Servers 10.0.0.4:

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    Wenn eine URL registriert ist, antwortet das Tool mit URL reservation successfully added.

    Verwenden Sie zum Löschen einer registrierten URL den Befehl delete urlacl:

    netsh http delete urlacl url=<URL>
    
  7. Registrieren Sie X.509-Zertifikate auf dem Server.

    Verwenden Sie das Tool netsh.exe, um Zertifikate für die App zu registrieren:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: gibt die lokale IP-Adresse für die Bindung an. Verwenden Sie keine Platzhalterbindung. Verwenden Sie eine gültige IP-Adresse.
    • <PORT>: gibt den Port für die Bindung an
    • <THUMBPRINT>: der Zertifikatsfingerabdruck X.509
    • <GUID>: eine vom Entwickler generierte GUID zur Darstellung der App zu Informationszwecken

    Speichern Sie die GUID zu Referenzzwecken in der App als Paket-Tag:

    • In Visual Studio:
      • Öffnen Sie die Projekteigenschaften der App, indem Sie mit der rechten Maustaste auf die App im Projektmappen-Explorer klicken und Eigenschaften auswählen.
      • Wählen Sie die Registerkarte Paket aus.
      • Geben Sie die GUID ein, die Sie im Feld Tags erstellt haben.
    • Wenn Sie Visual Studio nicht verwenden:
      • Öffnen Sie die Projektdatei der App.

      • Fügen Sie einer neuen oder vorhandenen <PropertyGroup> mit der von Ihnen erstellten GUID eine <PackageTags>-Eigenschaft hinzu:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags>
        </PropertyGroup>
        

    Im folgenden Beispiel:

    • Die lokale IP-Adresse des Servers lautet 10.0.0.4.
    • Ein zufälliger Online-GUID-Generator stellt den Wert appid bereit.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Wenn ein Zertifikat registriert ist, antwortet das Tool mit SSL Certificate successfully added.

    Verwenden Sie zum Löschen einer Zertifikatsregistrierung den Befehl delete sslcert:

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Referenzdokumentation für netsh.exe:

  8. Führen Sie die App aus.

    Administratorberechtigungen sind nicht erforderlich, um die App auszuführen, wenn die Verbindung zum lokalen Host über HTTP (nicht HTTPS) mit einer Portnummer größer als 1024 erfolgt. Für andere Konfigurationen (z.B. über eine lokale IP-Adresse oder Bindung an Port 443) führen Sie die App mit Administratorberechtigungen aus.

    Die App antwortet auf die öffentliche IP-Adresse des Servers. In diesem Beispiel wird der Server aus dem Internet mit seiner öffentlichen IP-Adresse 104.214.79.47 erreicht.

    In diesem Beispiel wird ein Entwicklungszertifikat verwendet. Die Seite wird sicher geladen, nachdem die Warnung vor nicht vertrauenswürdigen Zertifikaten des Browsers umgangen wurde.

    Browserfenster mit Anzeige der geladenen Indexseite der App

Proxyserver und Lastenausgleichsszenarien

Für Apps, die von HTTP.sys gehostet werden und mit Anforderungen aus dem Internet oder einem Unternehmensnetzwerk interagieren, ist möglicherweise eine zusätzliche Konfiguration erforderlich, wenn sie hinter Proxyservern und Lastenausgleichsmodulen hosten. Weitere Informationen hierzu feinden Sie unter Konfigurieren von ASP.NET Core zur Verwendung mit Proxyservern und Lastenausgleich.

Abrufen detaillierter Zeitangaben mit „IHttpSysRequestTimingFeature“

IHttpSysRequestTimingFeature stellt detaillierte Zeitangaben für Anforderungen bereit:

  • Zeitstempel werden mithilfe von QueryPerformanceCounter abgerufen.
  • Die Zeitstempelhäufigkeit kann über QueryPerformanceFrequency abgerufen werden.
  • Der Index der Zeitangaben kann in HttpSysRequestTimingType umgewandelt werden, um zu ermitteln, wofür die Zeitangaben stehen.
  • Der Wert kann 0 lauten, wenn keine Zeitangaben für die aktuelle Anforderung verfügbar sind.
  • Erfordert Windows 10, Version 2004, Windows Server 2022 oder höher.
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();
    
    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timestamps = feature.Timestamps;

    for (var i = 0; i < timestamps.Length; i++)
    {
        var timestamp = timestamps[i];
        var timingType = (HttpSysRequestTimingType)i;

        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetTimestamp ruft den Zeitstempel für den angegebenen Zeittyp ab:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;
var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var timingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetTimestamp(timingType, out var timestamp))
    {
        logger.LogInformation("Timestamp {timingType}: {timestamp}",
                                          timingType, timestamp);
    }
    else
    {
        logger.LogInformation("Timestamp {timingType}: not available for the "
                                           + "current request",    timingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

IHttpSysRequestTimingFeature.TryGetElapsedTime gibt an, wie viel Zeit zwischen zwei angegebenen Zeitpunkten verstrichen ist:

using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Server.HttpSys;

var builder = WebApplication.CreateBuilder(args);

builder.WebHost.UseHttpSys();

var app = builder.Build();

app.Use((context, next) =>
{
    var feature = context.Features.GetRequiredFeature<IHttpSysRequestTimingFeature>();

    var loggerFactory = context.RequestServices.GetRequiredService<ILoggerFactory>();
    var logger = loggerFactory.CreateLogger("Sample");

    var startingTimingType = HttpSysRequestTimingType.RequestRoutingStart;
    var endingTimingType = HttpSysRequestTimingType.RequestRoutingEnd;

    if (feature.TryGetElapsedTime(startingTimingType, endingTimingType, out var elapsed))
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}: {elapsed}",
            startingTimingType,
            endingTimingType,
            elapsed);
    }
    else
    {
        logger.LogInformation(
            "Elapsed time {startingTimingType} to {endingTimingType}:"
            + " not available for the current request.",
            startingTimingType,
            endingTimingType);
    }

    return next(context);
});

app.MapGet("/", () => Results.Ok());

app.Run();

Erweiterte HTTP/2-Features zur Unterstützung von gRPC

Zusätzliche HTTP/2-Features in HTTP.sys zur Unterstützung von gRPC, einschließlich der Unterstützung für Antwortnachspanne und das Senden von Frames zum Zurücksetzen

Anforderungen zum Ausführen von gRPC mit HTTP.sys:

  • Windows 11 Build 22000 oder höher, Windows Server 2022 Build 20348 oder höher
  • TLS 1.2-Verbindung oder höher

Trailer

HTTP-Nachspanne ähneln den HTTP-Headers, jedoch werden sie erst gesendet, nachdem der Antworttext gesendet wurde. Für IIS und HTTP.sys werden nur HTTP/2-Antwortnachspanne unterstützt.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

Im vorherigen Beispielcode:

  • stellt SupportsTrailers sicher, dass Nachspanne für die Antwort unterstützt werden.
  • fügt DeclareTrailer dem Antwortheader Trailer den angegebenen Namen für den Nachspann hinzu. Das Deklarieren des Nachspanns einer Antwort ist optional, wird jedoch empfohlen. Wenn DeclareTrailer aufgerufen wird, muss der Nachspann deklariert werden, bevor Antwortheader gesendet werden.
  • fügt AppendTrailer den Nachspann an.

Reset

Durch die Option „Zurücksetzen“ kann der Server eine HTTP/2-Anforderung mit einem angegebenen Fehlercode zurücksetzen. Eine Anforderung zum Zurücksetzen wird als abgebrochen betrachtet.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset gibt im vorangehenden Codebeispiel den Fehlercode INTERNAL_ERROR an. Weitere Informationen zu HTTP/2-Fehlercodes finden Sie im Abschnitt HTTP/2-Spezifikationsfehlercode.

Ablaufverfolgung

Informationen zum Abrufen von Ablaufverfolgungen von „HTTP.sys“ finden Sie unter Verwaltungsszenarios für HTTP.sys.

Zusätzliche Ressourcen

HTTP.sys ist ein Webserver für ASP.NET Core, der nur unter Windows ausgeführt werden kann. HTTP.sys stellt eine Alternative zum Kestrel-Server dar und bietet einige Features, die in Kestrel fehlen.

Wichtig

HTTP.sys ist nicht mit dem ASP.NET Core-Modul kompatibel und kann nicht mit IIS oder IIS Express verwendet werden.

HTTP.sys unterstützt die folgenden Features:

  • Windows-Authentifizierung
  • Portfreigabe
  • HTTPS mit SNI
  • HTTP/2 über TLS (Windows 10 oder höher)
  • Direkte Dateiübertragung
  • Zwischenspeichern von Antworten
  • WebSockets (Windows 8 oder höher)

Unterstützte Windows-Versionen:

  • Windows 7 oder höher
  • Windows Server 2008 R2 oder höher

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Empfohlene Verwendung von HTTP.sys

HTTP.sys eignet sich für Bereitstellungen, auf die Folgendes zutrifft:

  • Sie müssen den Server ohne IIS direkt mit dem Internet verbinden.

    HTTP.sys kommuniziert direkt mit dem Internet

  • Eine interne Bereitstellung erfordert ein Feature, das in Kestrel nicht verfügbar ist. Weitere Informationen finden Sie unter Kestrel im Vergleich zu HTTP.sys.

    HTTP.sys kommuniziert direkt mit dem internen Netzwerk

Bei HTTP.sys handelt es sich um eine ausgereifte Technologie, die Schutz vor vielen Arten von Angriffen bietet und zudem die Stabilität, Sicherheit und Skalierbarkeit eines Webservers mit vollem Funktionsumfang bereitstellt. IIS selbst wird auf HTTP.sys als HTTP-Listener ausgeführt.

HTTP/2-Unterstützung

HTTP/2 ist für ASP.NET Core-Apps aktiviert, wenn die folgenden Basisanforderungen erfüllt sind:

  • Windows Server 2016/Windows 10 oder höher
  • ALPN-Verbindung (Application-Layer Protocol Negotiation)
  • TLS 1.2-Verbindung oder höher

Wenn eine HTTP/2-Verbindung hergestellt wurde, meldet HttpRequest.ProtocolHTTP/2.

HTTP/2 ist standardmäßig aktiviert. Für die Verbindung wird ein Fallback auf HTTP/1.1 ausgeführt, wenn keine HTTP/2-Verbindung hergestellt wurde. In einer zukünftigen Version von Windows werden HTTP/2-Konfigurationsflags verfügbar sein, einschließlich der Möglichkeit, HTTP/2 mit HTTP.sys zu deaktivieren.

HTTP/3-Unterstützung

HTTP/3 ist für ASP.NET Core-Apps aktiviert, wenn die folgenden Basisanforderungen erfüllt sind:

Die vorherigen Windows 11-Buildversionen erfordern möglicherweise die Verwendung eines Windows-Insider-Builds.

HTTP/3 wird anhand des Headers alt-svc als Upgrade von HTTP/1.1 oder HTTP/2 erkannt. Das bedeutet, dass die erste Anforderung normalerweise HTTP/1.1 oder HTTP/2 verwendet, bevor der Wechsel zu HTTP/3 erfolgt. Http.Sys fügt den alt-svc-Header nicht automatisch hinzu, er muss von der Anwendung hinzugefügt werden. Der folgende Code ist ein Middlewarebeispiel, das den alt-svc-Antwortheader hinzufügt.

app.Use((context, next) =>
{
    context.Response.Headers.AltSvc = "h3=\":443\"";
    return next(context);
});

Platzieren Sie den vorangehenden Code frühzeitig in der Anforderungspipeline.

Http.Sys unterstützt auch das Senden einer ALTSVC-HTTP/2-Protokollnachricht statt eines Antwortheaders, um den Client zu benachrichtigen, dass HTTP/3 verfügbar ist. Siehe dazu den EnableAltSvc-Registrierungsschlüssel. Dazu werden netsh sslcert-Bindungen benötigt, die anstelle von IP-Adressen Hostnamen verwenden.

Kernelmodusauthentifizierung mit Kerberos

HTTP.sys delegiert zur Kernelmodusauthentifizierung mit dem Kerberos-Authentifizierungsprotokoll. Die Benutzermodusauthentifizierung wird nicht von Kerberos und HTTP.sys unterstützt. Das Computerkonto muss zum Entschlüsseln des Kerberos-Tokens/-Tickets verwendet werden, das von Active Directory abgerufen und zur Authentifizierung des Benutzers vom Client an den Server weitergeleitet wird. Registrieren Sie den Dienstprinzipalnamen (SPN) für den Host, nicht für den Benutzer der App.

Empfohlene Verwendung von HTTP.sys

Konfigurieren der ASP.NET Core-App für die Verwendung von HTTP.sys

Rufen Sie die Erweiterungsmethode UseHttpSys auf, wenn Sie den Host erstellen, und geben Sie dabei alle erforderlichen HttpSysOptions-Objekte an. Im folgenden Beispiel werden Optionen auf ihre Standardwerte festgelegt:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

Die weitere Konfiguration von HTTP.sys erfolgt über Registrierungseinstellungen.

Weitere Informationen zu den HTTP.sys-Optionen finden Sie unter HttpSysOptions.

MaxRequestBodySize

Die maximal zulässige Größe eines Anforderungstexts in Bytes. Wenn dieser Wert auf null festgelegt wird, ist die maximale Größe für Anforderungstexte unbegrenzt. Dieser Grenzwert wirkt sich nicht auf Verbindungen aus, für die ein Upgrade durchgeführt wurde – diese sind immer unbegrenzt.

Die empfohlene Methode zum Überschreiben des Grenzwerts in einer ASP.NET Core-MVC-App für ein einzelnes IActionResult besteht im Verwenden von RequestSizeLimitAttribute in einer Aktionsmethode:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Eine Ausnahme wird ausgelöst, wenn die App versucht, den Grenzwert einer Anforderung zu konfigurieren, nachdem die App bereits mit dem Lesen der Anforderung begonnen hat. Sie können eine IsReadOnly-Eigenschaft verwenden, um darauf hinzuweisen, dass sich die MaxRequestBodySize-Eigenschaft im schreibgeschützten Zustand befindet, der Grenzwert also nicht mehr konfiguriert werden kann.

Wenn die App MaxRequestBodySize pro Anforderung außer Kraft setzen sollte, verwenden Sie das IHttpMaxRequestBodySizeFeature:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Wenn Sie Visual Studio verwenden, stellen Sie sicher, dass die App nicht für die Ausführung von IIS oder IIS Express konfiguriert ist.

In Visual Studio ist das Standardstartprofil auf IIS Express ausgerichtet. Wenn das Projekt als Konsolen-App ausgeführt werden soll, ändern Sie das ausgewählte Profil manuell, wie im folgenden Screenshot dargestellt:

Auswählen des Profils der App-Konsole

Konfigurieren von Windows Server

  1. Bestimmen Sie die Ports, die für die App geöffnet werden sollen, und verwenden Sie die Windows-Firewall oder das PowerShell-Cmdlet New-NetFirewallRule, um Firewall-Ports zu öffnen, damit der Datenverkehr HTTP.sys erreichen kann. In den folgenden Befehlen und der Appkonfiguration wird Port 443 verwendet.

  2. Öffnen Sie bei der Bereitstellung für eine Azure-VM die Ports in der Netzwerksicherheitsgruppe. In den folgenden Befehlen und der Appkonfiguration wird Port 443 verwendet.

  3. Beziehen Sie X.509-Zertifikate und installieren Sie sie, falls erforderlich.

    Erstellen Sie unter Windows selbstsignierte Zertifikate mit dem PowerShell-Cmdlet „New-SelfSignedCertificate“. Ein nicht unterstütztes Beispiel finden Sie unter UpdateIISExpressSSLForChrome.ps1.

    Installieren Sie entweder selbstsignierte oder CA-signierte Zertifikate im Speicher Lokaler Server>Persönlich des Servers.

  4. Wenn es sich bei der App um eine frameworkabhängige Bereitstellung handelt, installieren Sie .NET Core, .NET Framework oder beides (wenn es sich um eine .NET Core-App für das .NET Framework handelt).

    • .NET Core: Wenn die App .NET Core erfordert, rufen Sie den Installer für die .NET Core Runtime über .NET Core-Downloads ab, und führen Sie ihn aus. Installieren Sie nicht das vollständige SDK auf dem Server.
    • .NET Framework: Erfordert die App .NET Framework, rufen Sie das .NET Framework-Installationshandbuch auf. Installieren Sie das erforderliche .NET Framework. Der Installer für das neueste .NET Framework steht auf der Seite .NET Core-Downloads zur Verfügung.

    Wenn die App eine eigenständige Bereitstellung ist, enthält die App die Runtime in ihrer Bereitstellung. Es ist keine Frameworkinstallation auf dem Server erforderlich.

  5. Konfigurieren Sie URLs und Ports in der App.

    Standardmäßig ist ASP.NET Core an http://localhost:5000 gebunden. Zum Konfigurieren von URL-Präfixen und Ports stehen folgende Optionen zur Verfügung:

    Das folgende Codebeispiel zeigt, wie Sie UrlPrefixes mit der lokalen IP-Adresse 10.0.0.4 des Servers auf Port 443 verwenden:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    Ein Vorteil von UrlPrefixes besteht darin, dass bei falsch formatierten Präfixen sofort eine Fehlermeldung generiert wird.

    Die Einstellungen in UrlPrefixes überschreiben die Einstellungen für UseUrls/urls/ASPNETCORE_URLS. Daher bieten UseUrls, urls und die Umgebungsvariable ASPNETCORE_URLS den Vorteil, dass sie den Wechsel zwischen Kestrel und HTTP.sys vereinfachen.

    HTTP.sys verwendet die HTTP Server-API-UrlPrefix-Zeichenfolgenformate.

    Warnung

    Allgemeine Platzhalterbindungen (http://*:80/ und http://+:80) dürfen nicht verwendet werden. Platzhalterbindungen auf oberster Ebene gefährden die Sicherheit Ihrer App. Dies gilt für starke und schwache Platzhalter. Verwenden Sie statt Platzhaltern explizite Hostnamen oder IP-Adressen. Platzhalterbindungen in untergeordneten Domänen (z.B. *.mysub.com) stellen kein Sicherheitsrisiko dar, wenn Sie die gesamte übergeordnete Domäne steuern (im Gegensatz zu *.com, das angreifbar ist). Weitere Informationen finden Sie unter RFC 9110: Abschnitt 7.2. Host und :authority.

  6. URL-Präfixe können vorab auf dem Server registriert werden.

    Das integrierte Tool für die Konfiguration von HTTP.sys ist netsh.exe. Mithilfe von netsh.exe können Sie URL-Präfixe reservieren und X.509-Zertifikate zuweisen. Das Tool erfordert Administratorrechte.

    Verwenden Sie das Tool netsh.exe, um die URLs für die App zu registrieren:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: Der vollqualifizierte Uniform Resource Locator (URL). Verwenden Sie keine Platzhalterbindung. Verwenden Sie einen gültigen Hostnamen oder eine gültige lokale IP-Adresse. Die URL muss einen nachgestellten Schrägstrich enthalten.
    • <USER>: gibt den Benutzer oder den Benutzergruppennamen an

    Im folgenden Beispiel ist die lokale IP-Adresse des Servers 10.0.0.4:

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    Wenn eine URL registriert ist, antwortet das Tool mit URL reservation successfully added.

    Verwenden Sie zum Löschen einer registrierten URL den Befehl delete urlacl:

    netsh http delete urlacl url=<URL>
    
  7. Registrieren Sie X.509-Zertifikate auf dem Server.

    Verwenden Sie das Tool netsh.exe, um Zertifikate für die App zu registrieren:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: gibt die lokale IP-Adresse für die Bindung an. Verwenden Sie keine Platzhalterbindung. Verwenden Sie eine gültige IP-Adresse.
    • <PORT>: gibt den Port für die Bindung an
    • <THUMBPRINT>: der Zertifikatsfingerabdruck X.509
    • <GUID>: eine vom Entwickler generierte GUID zur Darstellung der App zu Informationszwecken

    Speichern Sie die GUID zu Referenzzwecken in der App als Paket-Tag:

    • In Visual Studio:
      • Öffnen Sie die Projekteigenschaften der App, indem Sie mit der rechten Maustaste auf die App im Projektmappen-Explorer klicken und Eigenschaften auswählen.
      • Wählen Sie die Registerkarte Paket aus.
      • Geben Sie die GUID ein, die Sie im Feld Tags erstellt haben.
    • Wenn Sie Visual Studio nicht verwenden:
      • Öffnen Sie die Projektdatei der App.

      • Fügen Sie einer neuen oder vorhandenen <PropertyGroup> mit der von Ihnen erstellten GUID eine <PackageTags>-Eigenschaft hinzu:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags>
        </PropertyGroup>
        

    Im folgenden Beispiel:

    • Die lokale IP-Adresse des Servers lautet 10.0.0.4.
    • Ein zufälliger Online-GUID-Generator stellt den Wert appid bereit.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Wenn ein Zertifikat registriert ist, antwortet das Tool mit SSL Certificate successfully added.

    Verwenden Sie zum Löschen einer Zertifikatsregistrierung den Befehl delete sslcert:

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Referenzdokumentation für netsh.exe:

  8. Führen Sie die App aus.

    Administratorberechtigungen sind nicht erforderlich, um die App auszuführen, wenn die Verbindung zum lokalen Host über HTTP (nicht HTTPS) mit einer Portnummer größer als 1024 erfolgt. Für andere Konfigurationen (z.B. über eine lokale IP-Adresse oder Bindung an Port 443) führen Sie die App mit Administratorberechtigungen aus.

    Die App antwortet auf die öffentliche IP-Adresse des Servers. In diesem Beispiel wird der Server aus dem Internet mit seiner öffentlichen IP-Adresse 104.214.79.47 erreicht.

    In diesem Beispiel wird ein Entwicklungszertifikat verwendet. Die Seite wird sicher geladen, nachdem die Warnung vor nicht vertrauenswürdigen Zertifikaten des Browsers umgangen wurde.

    Browserfenster mit Anzeige der geladenen Indexseite der App

Proxyserver und Lastenausgleichsszenarien

Für Apps, die von HTTP.sys gehostet werden und mit Anforderungen aus dem Internet oder einem Unternehmensnetzwerk interagieren, ist möglicherweise eine zusätzliche Konfiguration erforderlich, wenn sie hinter Proxyservern und Lastenausgleichsmodulen hosten. Weitere Informationen hierzu feinden Sie unter Konfigurieren von ASP.NET Core zur Verwendung mit Proxyservern und Lastenausgleich.

Erweiterte HTTP/2-Features zur Unterstützung von gRPC

Zusätzliche HTTP/2-Features in HTTP.sys zur Unterstützung von gRPC, einschließlich der Unterstützung für Antwortnachspanne und das Senden von Frames zum Zurücksetzen

Anforderungen zum Ausführen von gRPC mit HTTP.sys:

  • Windows 11 Build 22000 oder höher, Windows Server 2022 Build 20348 oder höher
  • TLS 1.2-Verbindung oder höher

Trailer

HTTP-Nachspanne ähneln den HTTP-Headers, jedoch werden sie erst gesendet, nachdem der Antworttext gesendet wurde. Für IIS und HTTP.sys werden nur HTTP/2-Antwortnachspanne unterstützt.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

Im vorherigen Beispielcode:

  • stellt SupportsTrailers sicher, dass Nachspanne für die Antwort unterstützt werden.
  • fügt DeclareTrailer dem Antwortheader Trailer den angegebenen Namen für den Nachspann hinzu. Das Deklarieren des Nachspanns einer Antwort ist optional, wird jedoch empfohlen. Wenn DeclareTrailer aufgerufen wird, muss der Nachspann deklariert werden, bevor Antwortheader gesendet werden.
  • fügt AppendTrailer den Nachspann an.

Reset

Durch die Option „Zurücksetzen“ kann der Server eine HTTP/2-Anforderung mit einem angegebenen Fehlercode zurücksetzen. Eine Anforderung zum Zurücksetzen wird als abgebrochen betrachtet.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset gibt im vorangehenden Codebeispiel den Fehlercode INTERNAL_ERROR an. Weitere Informationen zu HTTP/2-Fehlercodes finden Sie im Abschnitt HTTP/2-Spezifikationsfehlercode.

Zusätzliche Ressourcen

HTTP.sys ist ein Webserver für ASP.NET Core, der nur unter Windows ausgeführt werden kann. HTTP.sys stellt eine Alternative zum Kestrel-Server dar und bietet einige Features, die in Kestrel fehlen.

Wichtig

HTTP.sys ist nicht mit dem ASP.NET Core-Modul kompatibel und kann nicht mit IIS oder IIS Express verwendet werden.

HTTP.sys unterstützt die folgenden Features:

  • Windows-Authentifizierung
  • Portfreigabe
  • HTTPS mit SNI
  • HTTP/2 über TLS (Windows 10 oder höher)
  • Direkte Dateiübertragung
  • Zwischenspeichern von Antworten
  • WebSockets (Windows 8 oder höher)

Unterstützte Windows-Versionen:

  • Windows 7 oder höher
  • Windows Server 2008 R2 oder höher

Anzeigen oder Herunterladen von Beispielcode (Vorgehensweise zum Herunterladen)

Empfohlene Verwendung von HTTP.sys

HTTP.sys eignet sich für Bereitstellungen, auf die Folgendes zutrifft:

  • Sie müssen den Server ohne IIS direkt mit dem Internet verbinden.

    HTTP.sys kommuniziert direkt mit dem Internet

  • Eine interne Bereitstellung erfordert ein Feature, das in Kestrel nicht verfügbar ist. Weitere Informationen finden Sie unter Kestrel im Vergleich zu HTTP.sys.

    HTTP.sys kommuniziert direkt mit dem internen Netzwerk

Bei HTTP.sys handelt es sich um eine ausgereifte Technologie, die Schutz vor vielen Arten von Angriffen bietet und zudem die Stabilität, Sicherheit und Skalierbarkeit eines Webservers mit vollem Funktionsumfang bereitstellt. IIS selbst wird auf HTTP.sys als HTTP-Listener ausgeführt.

HTTP/2-Unterstützung

HTTP/2 ist für ASP.NET Core-Apps aktiviert, wenn die folgenden Basisanforderungen erfüllt sind:

  • Windows Server 2016/Windows 10 oder höher
  • ALPN-Verbindung (Application-Layer Protocol Negotiation)
  • TLS 1.2-Verbindung oder höher

Wenn eine HTTP/2-Verbindung hergestellt wurde, meldet HttpRequest.ProtocolHTTP/2.

HTTP/2 ist standardmäßig aktiviert. Für die Verbindung wird ein Fallback auf HTTP/1.1 ausgeführt, wenn keine HTTP/2-Verbindung hergestellt wurde. In einer zukünftigen Version von Windows werden HTTP/2-Konfigurationsflags verfügbar sein, einschließlich der Möglichkeit, HTTP/2 mit HTTP.sys zu deaktivieren.

Kernelmodusauthentifizierung mit Kerberos

HTTP.sys delegiert zur Kernelmodusauthentifizierung mit dem Kerberos-Authentifizierungsprotokoll. Die Benutzermodusauthentifizierung wird nicht von Kerberos und HTTP.sys unterstützt. Das Computerkonto muss zum Entschlüsseln des Kerberos-Tokens/-Tickets verwendet werden, das von Active Directory abgerufen und zur Authentifizierung des Benutzers vom Client an den Server weitergeleitet wird. Registrieren Sie den Dienstprinzipalnamen (SPN) für den Host, nicht für den Benutzer der App.

Empfohlene Verwendung von HTTP.sys

Konfigurieren der ASP.NET Core-App für die Verwendung von HTTP.sys

Rufen Sie die Erweiterungsmethode UseHttpSys auf, wenn Sie den Host erstellen, und geben Sie dabei alle erforderlichen HttpSysOptions-Objekte an. Im folgenden Beispiel werden Optionen auf ihre Standardwerte festgelegt:

public static IHostBuilder CreateHostBuilder(string[] args) =>
    Host.CreateDefaultBuilder(args)
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseHttpSys(options =>
            {
                options.AllowSynchronousIO = false;
                options.Authentication.Schemes = AuthenticationSchemes.None;
                options.Authentication.AllowAnonymous = true;
                options.MaxConnections = null;
                options.MaxRequestBodySize = 30000000;
                options.UrlPrefixes.Add("http://localhost:5005");
            });
            webBuilder.UseStartup<Startup>();
        });

Die weitere Konfiguration von HTTP.sys erfolgt über Registrierungseinstellungen.

HTTP.sys-Optionen

Eigenschaft BESCHREIBUNG Standard
AllowSynchronousIO Hiermit steuern Sie, ob eine synchrone Eingabe/Ausgabe für HttpContext.Request.Body und HttpContext.Response.Body zulässig ist. false
Authentication.AllowAnonymous Hiermit lassen Sie anonyme Anforderungen zu. true
Authentication.Schemes Hiermit geben Sie die zulässigen Authentifizierungsschemas an. Diese Eigenschaft kann jederzeit vor dem Verwerfen des Listeners geändert werden. Die Werte werden durch die AuthenticationSchemes-Enumeration bereitgestellt: Basic, Kerberos, Negotiate, None und NTLM. None
EnableResponseCaching Hiermit wird das Caching im Kernelmodus für Antworten mit geeigneten Headern versucht. Die Antwort enthält möglicherweise keine Set-Cookie-, Vary- oder Pragma-Header. Sie muss einen Cache-Control-Header enthalten, der vom Typ public ist und entweder ein shared-max-age- oder ein max-age-Wert oder ein Expires-Header ist. true
Http503Verbosity Das Verhalten von „HTTP.sys“, wenn Anforderungen aufgrund von Drosselungsbedingungen abgelehnt werden. Http503VerbosityLevel.
Basic
MaxAccepts Die maximale Anzahl gleichzeitiger Aufrufe. 5 × -Umgebung.
ProcessorCount
MaxConnections Die maximale Anzahl an gleichzeitigen Verbindungen, die akzeptiert werden. Verwenden Sie -1, um eine unbegrenzte Anzahl anzugeben. Verwenden Sie null, um die computerübergreifende Einstellung der Registrierung zu verwenden. null
(computerweite
Einstellung)
MaxRequestBodySize Informationen hierzu finden Sie im Abschnitt MaxRequestBodySize. 30.000.000 Bytes
(~28,6 MB)
RequestQueueLimit Die maximale Anzahl von Anforderungen, die in der Warteschlange gespeichert werden kann. 1000
RequestQueueMode Hiermit wird angegeben, ob der Server für die Erstellung und Konfiguration der Anforderungswarteschlange verantwortlich ist oder ob ein Anfügen an eine bestehende Warteschlange erfolgen soll.
Die meisten vorhandenen Konfigurationsoptionen gelten beim Anfügen an eine vorhandene Warteschlange nicht.
RequestQueueMode.Create
RequestQueueName Der Name der HTTP.sys-Anforderungswarteschlange. null (Anonyme Warteschlange)
ThrowWriteExceptions Hiermit geben Sie an, ob Schreibvorgänge für Antworttext, die einen Fehler zurückgeben, weil die Verbindung zum Client getrennt wird, eine Ausnahme auslösen oder normal beendet werden. false
(normal beenden)
Timeouts Machen Sie die HTTP.sys-Konfiguration TimeoutManager verfügbar. Diese kann auch in der Registrierung konfiguriert werden. Unter folgenden API-Links finden Sie Informationen zu den einzelnen Einstellungen sowie die Standardwerte:
UrlPrefixes Geben Sie die UrlPrefixCollection an, die bei „HTTP.sys“ registriert werden soll. Besonders nützlich ist die Eigenschaft UrlPrefixCollection.Add, mit der Sie der Sammlung ein Präfix hinzufügen können. Diese Eigenschaften können jederzeit vor dem Verwerfen des Listeners geändert werden.

MaxRequestBodySize

Die maximal zulässige Größe eines Anforderungstexts in Bytes. Wenn dieser Wert auf null festgelegt wird, ist die maximale Größe für Anforderungstexte unbegrenzt. Dieser Grenzwert wirkt sich nicht auf Verbindungen aus, für die ein Upgrade durchgeführt wurde – diese sind immer unbegrenzt.

Die empfohlene Methode zum Überschreiben des Grenzwerts in einer ASP.NET Core-MVC-App für ein einzelnes IActionResult besteht im Verwenden von RequestSizeLimitAttribute in einer Aktionsmethode:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Eine Ausnahme wird ausgelöst, wenn die App versucht, den Grenzwert einer Anforderung zu konfigurieren, nachdem die App bereits mit dem Lesen der Anforderung begonnen hat. Sie können eine IsReadOnly-Eigenschaft verwenden, um darauf hinzuweisen, dass sich die MaxRequestBodySize-Eigenschaft im schreibgeschützten Zustand befindet, der Grenzwert also nicht mehr konfiguriert werden kann.

Wenn die App MaxRequestBodySize pro Anforderung außer Kraft setzen sollte, verwenden Sie das IHttpMaxRequestBodySizeFeature:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env, 
    ILogger<Startup> logger, IServer server)
{
    app.Use(async (context, next) =>
    {
        context.Features.Get<IHttpMaxRequestBodySizeFeature>()
            .MaxRequestBodySize = 10 * 1024;

        var serverAddressesFeature = 
            app.ServerFeatures.Get<IServerAddressesFeature>();
        var addresses = string.Join(", ", serverAddressesFeature?.Addresses);

        logger.LogInformation("Addresses: {Addresses}", addresses);

        await next.Invoke();
    });

    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }
    else
    {
        app.UseExceptionHandler("/Error");
    }

    app.UseStaticFiles();
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapRazorPages();
    });
}

Wenn Sie Visual Studio verwenden, stellen Sie sicher, dass die App nicht für die Ausführung von IIS oder IIS Express konfiguriert ist.

In Visual Studio ist das Standardstartprofil auf IIS Express ausgerichtet. Wenn das Projekt als Konsolen-App ausgeführt werden soll, ändern Sie das ausgewählte Profil manuell, wie im folgenden Screenshot dargestellt:

Auswählen des Profils der App-Konsole

Konfigurieren von Windows Server

  1. Bestimmen Sie die Ports, die für die App geöffnet werden sollen, und verwenden Sie die Windows-Firewall oder das PowerShell-Cmdlet New-NetFirewallRule, um Firewall-Ports zu öffnen, damit der Datenverkehr HTTP.sys erreichen kann. In den folgenden Befehlen und der Appkonfiguration wird Port 443 verwendet.

  2. Öffnen Sie bei der Bereitstellung für eine Azure-VM die Ports in der Netzwerksicherheitsgruppe. In den folgenden Befehlen und der Appkonfiguration wird Port 443 verwendet.

  3. Beziehen Sie X.509-Zertifikate und installieren Sie sie, falls erforderlich.

    Erstellen Sie unter Windows selbstsignierte Zertifikate mit dem PowerShell-Cmdlet „New-SelfSignedCertificate“. Ein nicht unterstütztes Beispiel finden Sie unter UpdateIISExpressSSLForChrome.ps1.

    Installieren Sie entweder selbstsignierte oder CA-signierte Zertifikate im Speicher Lokaler Server>Persönlich des Servers.

  4. Wenn es sich bei der App um eine frameworkabhängige Bereitstellung handelt, installieren Sie .NET Core, .NET Framework oder beides (wenn es sich um eine .NET Core-App für das .NET Framework handelt).

    • .NET Core: Wenn die App .NET Core erfordert, rufen Sie den Installer für die .NET Core Runtime über .NET Core-Downloads ab, und führen Sie ihn aus. Installieren Sie nicht das vollständige SDK auf dem Server.
    • .NET Framework: Erfordert die App .NET Framework, rufen Sie das .NET Framework-Installationshandbuch auf. Installieren Sie das erforderliche .NET Framework. Der Installer für das neueste .NET Framework steht auf der Seite .NET Core-Downloads zur Verfügung.

    Wenn die App eine eigenständige Bereitstellung ist, enthält die App die Runtime in ihrer Bereitstellung. Es ist keine Frameworkinstallation auf dem Server erforderlich.

  5. Konfigurieren Sie URLs und Ports in der App.

    Standardmäßig ist ASP.NET Core an http://localhost:5000 gebunden. Zum Konfigurieren von URL-Präfixen und Ports stehen folgende Optionen zur Verfügung:

    Das folgende Codebeispiel zeigt, wie Sie UrlPrefixes mit der lokalen IP-Adresse 10.0.0.4 des Servers auf Port 443 verwenden:

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseHttpSys(options =>
                {
                    options.UrlPrefixes.Add("https://10.0.0.4:443");
                });
                webBuilder.UseStartup<Startup>();
            });
    

    Ein Vorteil von UrlPrefixes besteht darin, dass bei falsch formatierten Präfixen sofort eine Fehlermeldung generiert wird.

    Die Einstellungen in UrlPrefixes überschreiben die Einstellungen für UseUrls/urls/ASPNETCORE_URLS. Daher bieten UseUrls, urls und die Umgebungsvariable ASPNETCORE_URLS den Vorteil, dass sie den Wechsel zwischen Kestrel und HTTP.sys vereinfachen.

    HTTP.sys verwendet die HTTP Server-API-UrlPrefix-Zeichenfolgenformate.

    Warnung

    Allgemeine Platzhalterbindungen (http://*:80/ und http://+:80) dürfen nicht verwendet werden. Platzhalterbindungen auf oberster Ebene gefährden die Sicherheit Ihrer App. Dies gilt für starke und schwache Platzhalter. Verwenden Sie statt Platzhaltern explizite Hostnamen oder IP-Adressen. Platzhalterbindungen in untergeordneten Domänen (z.B. *.mysub.com) stellen kein Sicherheitsrisiko dar, wenn Sie die gesamte übergeordnete Domäne steuern (im Gegensatz zu *.com, das angreifbar ist). Weitere Informationen finden Sie unter RFC 9110: Abschnitt 7.2. Host und :authority.

  6. URL-Präfixe können vorab auf dem Server registriert werden.

    Das integrierte Tool für die Konfiguration von HTTP.sys ist netsh.exe. Mithilfe von netsh.exe können Sie URL-Präfixe reservieren und X.509-Zertifikate zuweisen. Das Tool erfordert Administratorrechte.

    Verwenden Sie das Tool netsh.exe, um die URLs für die App zu registrieren:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: Der vollqualifizierte Uniform Resource Locator (URL). Verwenden Sie keine Platzhalterbindung. Verwenden Sie einen gültigen Hostnamen oder eine gültige lokale IP-Adresse. Die URL muss einen nachgestellten Schrägstrich enthalten.
    • <USER>: gibt den Benutzer oder den Benutzergruppennamen an

    Im folgenden Beispiel ist die lokale IP-Adresse des Servers 10.0.0.4:

    netsh http add urlacl url=https://10.0.0.4:443/ user=Users
    

    Wenn eine URL registriert ist, antwortet das Tool mit URL reservation successfully added.

    Verwenden Sie zum Löschen einer registrierten URL den Befehl delete urlacl:

    netsh http delete urlacl url=<URL>
    
  7. Registrieren Sie X.509-Zertifikate auf dem Server.

    Verwenden Sie das Tool netsh.exe, um Zertifikate für die App zu registrieren:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: gibt die lokale IP-Adresse für die Bindung an. Verwenden Sie keine Platzhalterbindung. Verwenden Sie eine gültige IP-Adresse.
    • <PORT>: gibt den Port für die Bindung an
    • <THUMBPRINT>: der Zertifikatsfingerabdruck X.509
    • <GUID>: eine vom Entwickler generierte GUID zur Darstellung der App zu Informationszwecken

    Speichern Sie die GUID zu Referenzzwecken in der App als Paket-Tag:

    • In Visual Studio:
      • Öffnen Sie die Projekteigenschaften der App, indem Sie mit der rechten Maustaste auf die App im Projektmappen-Explorer klicken und Eigenschaften auswählen.
      • Wählen Sie die Registerkarte Paket aus.
      • Geben Sie die GUID ein, die Sie im Feld Tags erstellt haben.
    • Wenn Sie Visual Studio nicht verwenden:
      • Öffnen Sie die Projektdatei der App.

      • Fügen Sie einer neuen oder vorhandenen <PropertyGroup> mit der von Ihnen erstellten GUID eine <PackageTags>-Eigenschaft hinzu:

        <PropertyGroup>
          <PackageTags>00001111-aaaa-2222-bbbb-3333cccc4444</PackageTags>
        </PropertyGroup>
        

    Im folgenden Beispiel:

    • Die lokale IP-Adresse des Servers lautet 10.0.0.4.
    • Ein zufälliger Online-GUID-Generator stellt den Wert appid bereit.
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Wenn ein Zertifikat registriert ist, antwortet das Tool mit SSL Certificate successfully added.

    Verwenden Sie zum Löschen einer Zertifikatsregistrierung den Befehl delete sslcert:

    netsh http delete sslcert ipport=<IP>:<PORT>
    

    Referenzdokumentation für netsh.exe:

  8. Führen Sie die App aus.

    Administratorberechtigungen sind nicht erforderlich, um die App auszuführen, wenn die Verbindung zum lokalen Host über HTTP (nicht HTTPS) mit einer Portnummer größer als 1024 erfolgt. Für andere Konfigurationen (z.B. über eine lokale IP-Adresse oder Bindung an Port 443) führen Sie die App mit Administratorberechtigungen aus.

    Die App antwortet auf die öffentliche IP-Adresse des Servers. In diesem Beispiel wird der Server aus dem Internet mit seiner öffentlichen IP-Adresse 104.214.79.47 erreicht.

    In diesem Beispiel wird ein Entwicklungszertifikat verwendet. Die Seite wird sicher geladen, nachdem die Warnung vor nicht vertrauenswürdigen Zertifikaten des Browsers umgangen wurde.

    Browserfenster mit Anzeige der geladenen Indexseite der App

Proxyserver und Lastenausgleichsszenarien

Für Apps, die von HTTP.sys gehostet werden und mit Anforderungen aus dem Internet oder einem Unternehmensnetzwerk interagieren, ist möglicherweise eine zusätzliche Konfiguration erforderlich, wenn sie hinter Proxyservern und Lastenausgleichsmodulen hosten. Weitere Informationen hierzu feinden Sie unter Konfigurieren von ASP.NET Core zur Verwendung mit Proxyservern und Lastenausgleich.

Erweiterte HTTP/2-Features zur Unterstützung von gRPC

Zusätzliche HTTP/2-Features in HTTP.sys zur Unterstützung von gRPC, einschließlich der Unterstützung für Antwortnachspanne und das Senden von Frames zum Zurücksetzen

Anforderungen zum Ausführen von gRPC mit HTTP.sys:

  • Windows 10, OS Build 19041.508 oder höher
  • TLS 1.2-Verbindung oder höher

Trailer

HTTP-Nachspanne ähneln den HTTP-Headers, jedoch werden sie erst gesendet, nachdem der Antworttext gesendet wurde. Für IIS und HTTP.sys werden nur HTTP/2-Antwortnachspanne unterstützt.

if (httpContext.Response.SupportsTrailers())
{
    httpContext.Response.DeclareTrailer("trailername");	

    // Write body
    httpContext.Response.WriteAsync("Hello world");

    httpContext.Response.AppendTrailer("trailername", "TrailerValue");
}

Im vorherigen Beispielcode:

  • stellt SupportsTrailers sicher, dass Nachspanne für die Antwort unterstützt werden.
  • fügt DeclareTrailer dem Antwortheader Trailer den angegebenen Namen für den Nachspann hinzu. Das Deklarieren des Nachspanns einer Antwort ist optional, wird jedoch empfohlen. Wenn DeclareTrailer aufgerufen wird, muss der Nachspann deklariert werden, bevor Antwortheader gesendet werden.
  • fügt AppendTrailer den Nachspann an.

Reset

Durch die Option „Zurücksetzen“ kann der Server eine HTTP/2-Anforderung mit einem angegebenen Fehlercode zurücksetzen. Eine Anforderung zum Zurücksetzen wird als abgebrochen betrachtet.

var resetFeature = httpContext.Features.Get<IHttpResetFeature>();
resetFeature.Reset(errorCode: 2);

Reset gibt im vorangehenden Codebeispiel den Fehlercode INTERNAL_ERROR an. Weitere Informationen zu HTTP/2-Fehlercodes finden Sie im Abschnitt HTTP/2-Spezifikationsfehlercode.

Zusätzliche Ressourcen