implementacja serwera internetowegoHTTP.sys w ASP.NET Core

Note

Nie jest to najnowsza wersja tego artykułu. Aby uzyskać bieżącą wersję, zobacz artykuł w wersji .NET 10.

Warning

Ta wersja ASP.NET Core nie jest już obsługiwana. Aby uzyskać więcej informacji, zobacz .NET i .NET Core Support Policy. Aby uzyskać bieżącą wersję, zobacz artykuł w wersji .NET 10.

Przez Tom Dykstra i Chris Ross

HTTP.sys jest serwerem sieci Web dla ASP.NET Core, który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają. W tym artykule wyjaśniono, kiedy używać HTTP.sys, jak go skonfigurować oraz jak sprawdzić żądania i informacje TLS.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Uwierzytelnianie Windows
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Protokół HTTP/3 za pośrednictwem protokołu TLS (Windows 11 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)
  • Dostosowywalne deskryptory zabezpieczeń
  • Automatyczne eksmisja puli pamięci

System operacyjny musi być obsługiwany przez docelową wersję .NET aplikacji. Aby uzyskać informacje o obsługiwanych wersjach Windows, zobacz Instalowanie .NET w Windows. Dostępność HTTP.sys w starszych wersjach Windows nie oznacza obsługi tych wersji przez bieżące wersje ASP.NET Core. Poszczególne funkcje mogą mieć dodatkowe wymagania Windows, zgodnie z opisem w poniższych sekcjach.

Wyświetlanie lub pobieranie przykładowego kodu (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. Same usługi IIS są uruchamiane jako odbiornik HTTP na podstawie HTTP.sys.

Obsługa protokołu HTTP/2

Protokół HTTP/2 jest włączony dla aplikacji ASP.NET Core, gdy spełnione są następujące podstawowe wymagania:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W wersjach systemu Windows, które to obsługują, opcja disablehttp2 w powiązaniu certyfikatu SSL netsh http wyłącza protokół HTTP/2 dla tego powiązania. Aby uzyskać dostępne opcje, zobacz netsh http.

Obsługa protokołu HTTP/3

Protokół HTTP/3 jest włączony dla aplikacji ASP.NET Core, gdy spełnione są następujące podstawowe wymagania:

  • Windows Server 2022/Windows 11 lub nowszy
  • Używane jest powiązanie URL https.
  • Ustawiono klucz rejestru EnableHttp3.

Poprzednie wersje kompilacji Windows 11 mogą wymagać użycia kompilacji Windows insider.

Protokół HTTP/3 jest wykrywany jako uaktualnienie z protokołu HTTP/1.1 lub HTTP/2 za pośrednictwem nagłówka alt-svc . Oznacza to, że pierwsze żądanie zwykle będzie używać protokołu HTTP/1.1 lub HTTP/2 przed przełączeniem do protokołu HTTP/3. Protokół Http.Sys nie dodaje automatycznie nagłówka alt-svc — musi zostać dodany przez aplikację. Poniższy kod to przykład oprogramowania pośredniczącego, który dodaje alt-svc nagłówek odpowiedzi.

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

Umieść poprzedni kod na początku potoku żądania.

Http.Sys obsługuje również wysyłanie komunikatu protokołu HTTP/2 AltSvc zamiast nagłówka odpowiedzi w celu powiadomienia klienta o dostępności protokołu HTTP/3. Zobacz klucz rejestru EnableAltSvc.

Note

Wymaga to powiązań netsh sslcert, które używają nazw hostów, a nie adresów IP. Zastąp ipport przez hostnameport w poniższych poleceniach netsh http add sslcert i zamień adres IP na nazwę hosta, na przykład www.example.com. Istnieje również znany problem polegający na tym, że użycie hostnameport kończy się niepowodzeniem, chyba że określono parametr certstorename. Domyślnie użyj certstorename=MY.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje uwierzytelnianie do trybu jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Włącz wzmacnianie zabezpieczeń tokenu powiązania kanału (CBT)

Tokeny wiązania kanału (CBT) wiążą uwierzytelnianie Windows z bazowym kanałem TLS, co pomaga ograniczyć ataki przekazywania NTLM i ataki typu man-in-the-middle.

Skonfiguruj wzmacnianie zabezpieczeń CBT za pomocą HttpAuthenticationHardeningLevel. Dostępne HttpAuthenticationHardeningLevel wartości to:

Value Behavior
Legacy Nie wymusza weryfikacji powiązania kanału ani nie uwidacznia bajtów CBT w aplikacji.
Medium (domyślnie) Weryfikuje cbts, gdy klienci je dostarczają, ale zezwala na ich nieobecność. Uwidacznia bajty CBT w aplikacji.
Strict Wymaga cbts na uwierzytelnionych żądaniach i odrzuca żądania bez nich. Uwidacznia bajty CBT w aplikacji.

Poniższy przykład włącza Strict wzmacnianie:

builder.WebHost.UseHttpSys(options =>
{
    options.HttpAuthenticationHardeningLevel =
        HttpAuthenticationHardeningLevel.Strict;
});

Jeśli HTTP.sys nie może zastosować Strict utwardzania, uruchamianie serwera kończy się niepowodzeniem z błędem HttpSysException. W przypadku Legacy lub Medium błąd stosowania ustawienia jest rejestrowany, a uruchamianie jest kontynuowane. Skonfigurowana wartość nie gwarantuje, że system operacyjny zastosował to ustawienie.

Warning

Strictwzmocnienie zabezpieczeń może spowodować niepowodzenie Windows authentication dla klientów lub serwerów proxy, które nie dostarczają prawidłowego CBT. Przetestuj zgodność klienta i zakończenie protokołu TLS w środowisku przed włączeniem go w środowisku produkcyjnym.

Podczas dołączania do istniejącej kolejki żądań skonfiguruj wzmocnienie zabezpieczeń na odbiorniku, który jest właścicielem grupy adresów URL. Aplikacja dołączająca nie stosuje konfiguracji grupy adresów URL.

Aby uzyskać dostęp do bajtów CBT, zobacz Pobieranie tokenów powiązań kanału.

Włącz wzmacnianie zabezpieczeń CBT dla punktów końcowych HTTPS, które używają Windows authentication, ustawiając przełącznik AppContext Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening na true. Ten przełącznik wybiera średnie wzmocnienie zabezpieczeń, które weryfikuje dostarczone CBTs, ale zezwala na ich nieobecność.

Włącz przełącznik w pliku projektu runtimeconfig.template.json :

{
  "configProperties": {
    "Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening": true
  }
}

Alternatywnie ustaw przełącznik programowo przed utworzeniem hosta w Program pliku:

AppContext.SetSwitch("Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening", true);

Warning

Wzmocnienie zabezpieczeń CBT jest domyślnie wyłączone. Włączenie tego może spowodować niepowodzenie uwierzytelniania Windows dla klientów lub proxy, które nie obsługują wiązania kanału. Dokładnie przetestuj w swoim środowisku przed włączeniem w środowisku produkcyjnym.

Obsługa buforowania odpowiedzi w trybie jądra

W niektórych scenariuszach duże ilości małych zapisów z dużym opóźnieniem mogą spowodować znaczny wpływ na wydajność.HTTP.sys Ten wpływ jest spowodowany brakiem Pipe buforu w implementacji HTTP.sys . Aby zwiększyć wydajność w tych scenariuszach, obsługa buforowania odpowiedzi jest uwzględniana w systemie HTTP.sys. Włącz buforowanie, ustawiając EnableKernelResponseBuffering na true. Buforowanie odpowiedzi powinno być włączone przez aplikację, która wykonuje synchroniczne operacje we/wy lub asynchroniczne operacje we/wy bez więcej niż jednego zaległego zapisu naraz. W tych scenariuszach buforowanie odpowiedzi może znacznie zwiększyć przepływność w przypadku połączeń o dużym opóźnieniu.

Aplikacje, które korzystają z asynchronicznych operacji we/wy i mogą mieć więcej niż jeden nieukończony zapis jednocześnie, nie powinny używać tej flagi. Włączenie tej flagi może spowodować wyższe użycie procesora CPU i pamięci przez HTTP.Sys.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę UseHttpSys rozszerzenia podczas kompilowania hosta, określając dowolną wymaganą metodę HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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();

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

Aby uzyskać więcej informacji na temat opcji HTTP.sys, zobacz HttpSysOptions.

Dostosowywanie deskryptorów zabezpieczeń

Kolejka żądań w HTTP.sys to struktura na poziomie jądra, która tymczasowo przechowuje przychodzące żądania HTTP, dopóki aplikacja nie będzie gotowa do ich przetworzenia. Zarządzaj dostępem do kolejki żądań przy użyciu polecenia RequestQueueSecurityDescriptor. Ustaw jako instancję GenericSecurityDescriptor podczas konfigurowania serwera HTTP.sys.

Dostosowując deskryptor zabezpieczeń, można zezwolić określonym użytkownikom lub grupom na dostęp do kolejki żądań oraz odmówić tego dostępu. Jest to przydatne w sytuacjach, gdy chcesz ograniczyć lub delegować obsługę żądań HTTP.sys na poziomie systemu operacyjnego.

Na przykład poniższy kod umożliwia wszystkim uwierzytelnionym użytkownikom, a odmawia dostępu gościom.

using System.Security.AccessControl;
using System.Security.Principal;
using Microsoft.AspNetCore.Server.HttpSys;

// Create a new security descriptor
var securityDescriptor = new CommonSecurityDescriptor(isContainer: false, isDS: false, sddlForm: string.Empty);

// Create a discretionary access control list (DACL)
var dacl = new DiscretionaryAcl(isContainer: false, isDS: false, capacity: 2);
dacl.AddAccess(
    AccessControlType.Allow,
    new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null),
    -1,
    InheritanceFlags.None,
    PropagationFlags.None
);
dacl.AddAccess(
    AccessControlType.Deny,
    new SecurityIdentifier(WellKnownSidType.BuiltinGuestsSid, null),
    -1,
    InheritanceFlags.None,
    PropagationFlags.None
);

// Assign the DACL to the security descriptor
securityDescriptor.DiscretionaryAcl = dacl;

// Configure HTTP.sys options
var builder = WebApplication.CreateBuilder();
builder.WebHost.UseHttpSys(options =>
{
    options.RequestQueueSecurityDescriptor = securityDescriptor;
});

Właściwość RequestQueueSecurityDescriptor ma zastosowanie tylko podczas tworzenia nowej kolejki żądań. Właściwość nie ma wpływu na istniejące kolejki żądań. Gdy RequestQueueMode ma wartość Attach, otwierana jest istniejąca kolejka, a opcje na poziomie kolejki, takie jak RequestQueueSecurityDescriptor i RequestQueueLimit, nie mają zastosowania. W trybie Attach ustawienia grupy adresów URL, takie jak limity czasu i wzmacnianie zabezpieczeń uwierzytelniania, muszą być skonfigurowane przez listener, do którego należy grupa adresów URL, a UrlPrefixes jest używany wyłącznie do obliczania PathBase. CreateOrAttach Nadal konfiguruje własną grupę adresów URL i rejestruje jej UrlPrefixes, nawet jeśli kolejka już istnieje; ustawienia prefiksów już zarejestrowanych przez inny odbiornik pozostają kontrolowane przez ten odbiornik.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. Ten limit nie wpływa na połączenia, które zostały uaktualnione, ponieważ są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy właściwość MaxRequestBodySize jest ustawiona jako tylko do odczytu, co oznacza, że jest za późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize żądanie, użyj polecenia 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);
});

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybieranie profilu aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj polecenia cmdlet Windows Firewall lub New-NetFirewallRule polecenia cmdlet programu PowerShell w celu otwarcia portów zapory w celu umożliwienia ruchu do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobiste.

  4. Jeśli aplikacja jest wdrożeniem zależnym od platformy, zainstaluj pasujące środowisko uruchomieniowe ASP.NET Core i środowisko uruchomieniowe .NET z .NET Downloads. Zestaw SDK .NET nie jest wymagany na serwerze. ASP.NET Core nie jest przeznaczony dla platformy .NET Framework. Aby uzyskać informacje o zawartości instalatora, zobacz Wybieranie poprawnego środowiska uruchomieniowego.

    Jeśli aplikacja jest wdrożeniem niezależnym, zawiera środowisko uruchomieniowe. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 443:

    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();
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes nadpisują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys rozpoznaje dwa typy symboli wieloznacznych w prefiksach adresów URL:

    • * jest słabym wiązaniem, znanym również jako wiązanie zapasowe. Jeśli prefiks adresu URL to http://*:5000, a coś innego jest powiązane z portem 5000, to powiązanie nie będzie używane.
    • + jest silnym wiązaniem. Jeśli prefiks adresu URL to http://+:5000, to powiązanie będzie używane przed innymi powiązaniami portu 5000.

    Aby uzyskać więcej informacji, zobacz Ciągi prefiksu URL.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

    Większość konfiguracji aplikacji i kontenerów definiuje tylko port nasłuchujący, taki jak port 80, bez określania innych ograniczeń, takich jak host lub ścieżka. HTTP_PORTS i HTTPS_PORTS to klucze konfiguracji, które określają porty nasłuchiwania dla Kestrel serwerów i HTTP.sys. Klucze można określić jako zmienne środowiskowe zdefiniowane przy użyciu prefiksów DOTNET_ lub ASPNETCORE_, albo ustawić je bezpośrednio za pomocą dowolnego innego źródła konfiguracji, takiego jak plik appsettings.json. Każda konfiguracja to rozdzielana średnikami lista wartości portów, jak pokazano w poniższym przykładzie:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Konfiguracja w przykładzie jest skrócona dla następującej specyfikacji, która definiuje schemat (HTTP lub HTTPS) i dowolny host lub adres IP:

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

    Klucze konfiguracji HTTP_PORTS i HTTPS_PORTS mają niższy priorytet. Jeśli inne adresy URL lub wartości są ustawiane bezpośrednio w kodzie, mogą zastąpić klucze konfiguracji. Skonfiguruj certyfikaty oddzielnie przy użyciu mechaniki specyficznej dla serwera dla protokołu HTTPS.

    Note

    Nie należy mylić klucza konfiguracji HTTPS_PORTS i zmiennej środowiskowej ASPNETCORE_HTTPS_PORTS, które ustawiają porty dla konfiguracji punktów końcowych Kestrel/HTTP.sys, z kluczem konfiguracji HTTPS_PORT i zmienną środowiskową ASPNETCORE_HTTPS_PORT, które ustawiają port dla middleware przekierowania HTTPS.

    Te klucze konfiguracji są równoważne powiązaniom symboli wieloznacznych najwyższego poziomu. Są one wygodne w środowiskach programistycznych i kontenerowych, ale unikaj symboli wieloznacznych podczas uruchamiania na maszynie, która może również hostować inne usługi.

  6. Wstępnie zarejestrować prefiksy adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: w pełni kwalifikowany ujednolicony lokalizator zasobów (URL). Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś, w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup> z identyfikatorem GUID, który utworzyłeś:

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

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator losowego identyfikatora appid GUID w trybie online zapewnia wartość .
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uruchom aplikację w ramach tożsamości autoryzowanej przez rezerwację adresu URL. Uprawnienia administratora są wymagane do konfigurowania rezerwacji adresów URL i powiązań certyfikatów, ale nie są wymagane do uruchamiania aplikacji, której tożsamość ma niezbędne uprawnienia do przestrzeni nazw. Powiązanie z lokalnym adresem IP lub portem 443 samo w sobie nie wymaga procesu aplikacji z podwyższonym poziomem uprawnień. Aby uzyskać więcej informacji, zobacz Rezerwacje, rejestracje i routing przestrzeni nazw.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Podczas przetwarzania żądania zarówno z nagłówkiem Content-Length, jak i nagłówkiem Transfer-Encoding, którego ostatnim kodowaniem jest chunked, HTTP.sys usuwa Content-Length z nagłówków żądań przekazywanych do aplikacji i domyślnie zamyka połączenie po udzieleniu odpowiedzi. Serwery proxy nie powinny wysyłać żądań ze sprzecznym sposobem wyznaczania ich granic. Takie zachowanie pomaga zapobiec przemytowi żądań; Nie oznacza to, że każde takie żądanie zostanie odrzucone przed dotarciem do aplikacji.

Inspekcja właściwości protokołu TLS i żądania

HTTP.sys udostępnia funkcje żądania na potrzeby inspekcji informacji TLS. Dostępność zależy od żądania, wersji Windows i konfiguracji HTTP.sys.

Uzyskiwanie wynegocjowanego pakietu szyfrowania TLS

ITlsHandshakeFeature uwidacznia wynegocjowany zestaw szyfrowania za pośrednictwem właściwości NegotiatedCipherSuite dla HTTP.sys. Funkcja nie jest dostępna dla żądania innego niż TLS. Właściwość może być nullnull, jeśli Windows nie obsługuje zapytania lub zapytanie kończy się niepowodzeniem.

var handshake = context.Features.Get<ITlsHandshakeFeature>();
if (handshake?.NegotiatedCipherSuite is { } cipherSuite)
{
    logger.LogInformation("Negotiated TLS cipher suite: {CipherSuite}", cipherSuite);
}
else
{
    logger.LogInformation("The negotiated TLS cipher suite isn't available.");
}

Odczyt TLS ClientHello

Użyj polecenia TryGetTlsClientHello, aby pobrać nieprzetworzone bajty protokołu TLS ClientHello w razie potrzeby. Konfiguracja usługi HTTPS musi mieć włączone HTTP_SERVICE_CONFIG_SSL_FLAG_ENABLE_CACHE_CLIENT_HELLO. Skonfigurowanie ASP.NET Core do używania HTTP.sys nie powoduje włączenia tej flagi natywnej. Zobacz HttpSetServiceConfiguration i HTTP_SERVICE_CONFIG_ID.

Najpierw wywołaj metodę z pustym zakresem, aby uzyskać wymagany rozmiar buforu, a następnie przydziel bufor i ponów próbę:

var feature = context.Features.GetRequiredFeature<IHttpSysRequestPropertyFeature>();
_ = feature.TryGetTlsClientHello(Span<byte>.Empty, out var requiredSize);

var pooled = requiredSize <= 1024 ? ArrayPool<byte>.Shared.Rent(requiredSize) : null;
var buffer = pooled ?? new byte[requiredSize];
try
{
    if (!feature.TryGetTlsClientHello(buffer, out var bytesReturned))
    {
        throw new InvalidOperationException(
            $"The TLS ClientHello buffer must be resized to {bytesReturned} bytes.");
    }

    logger.LogInformation("Retrieved {ByteCount} TLS ClientHello bytes.", bytesReturned);
}
finally
{
    if (pooled is not null)
    {
        ArrayPool<byte>.Shared.Return(pooled);
    }
}

Wykonywanie zapytań o inne właściwości żądania natywnego

TryGetRequestProperty udostępnia HttpQueryRequestProperty dla dowolnych właściwości żądania natywnego.

  • propertyId identyfikuje wartość z natywnego wyliczenia HTTP_REQUEST_PROPERTY.
  • qualifier zawiera opcjonalne bajty specyficzne dla właściwości. Pusty zakres jest przekazywany do Windows jako wskaźnik o wartości null.
  • output odbiera bajty natywne. Obiekt wywołujący musi je interpretować przy użyciu odpowiedniej natywnej struktury danych.
  • bytesReturned zawiera bajty zapisane w przypadku powodzenia. W przypadku błędu niewystarczającego buforu raportowanie wymaganego rozmiaru zależy od właściwości natywnej. W przypadku właściwości o stałym rozmiarze należy przydzielić bufor o rozmiarze odpowiedniej struktury natywnej zamiast zakładać, że zapytanie pustego buforu zgłasza wymagany rozmiar.

Poniższy przykład odpytuje właściwość TLS ClientHello za pomocą interfejsu API ogólnego przeznaczenia. Wymaga to tej samej natywnej konfiguracji buforowania ClientHello co TryGetTlsClientHello:

const int HttpRequestPropertyTlsClientHello = 11;
var feature = context.Features.GetRequiredFeature<IHttpSysRequestPropertyFeature>();
_ = feature.TryGetRequestProperty(
    HttpRequestPropertyTlsClientHello, qualifier: default, output: default,
    out var requiredSize);
var buffer = new byte[requiredSize];

if (!feature.TryGetRequestProperty(
    HttpRequestPropertyTlsClientHello, qualifier: default, output: buffer,
    out var bytesReturned))
{
    throw new InvalidOperationException(
        $"The request property buffer must be resized to {bytesReturned} bytes.");
}

logger.LogInformation("Retrieved {ByteCount} native request property bytes.", bytesReturned);

Pobieranie tokenów powiązania kanału

TryGetChannelBindingBytes zapewnia dostęp do bajtów powiązania kanału TLS:

var tls = context.Features.Get<ITlsConnectionFeature>();
if (tls is not null &&
    tls.TryGetChannelBindingBytes(ChannelBindingKind.Endpoint, out var token))
{
    logger.LogInformation("TLS endpoint binding contains {ByteCount} bytes.", token.Length);
}
else
{
    logger.LogInformation("TLS endpoint channel binding isn't available.");
}

HTTP.sys obsługuje element ChannelBindingKind.Endpointodpowiadający powiązaniu tls-server-end-point zdefiniowanemu przez RFC 5929. Inne rodzaje powiązań zwracają wartość false. Niedostępny token również zwraca false. Ujawnienie CBT wymaga, aby Medium lub Strict było stosowane przez HTTP.sys.

Pobieranie bajtów CBT nie powoduje uwierzytelnienia żądania ani wymuszania Strict wzmacniania zabezpieczeń. Zwrócone bajty zawierają strukturę Windows SEC_CHANNEL_BINDINGS i jej dane powiązania, a nie tylko skrót certyfikatu.

Uzyskiwanie szczegółowych informacji o chronometrażu za pomocą funkcji IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature zawiera szczegółowe informacje o chronometrażu dla żądań:

  • Znaczniki czasu są uzyskiwane przy użyciu elementu QueryPerformanceCounter.
  • Częstotliwość sygnatury czasowej można uzyskać za pośrednictwem metody QueryPerformanceFrequency.
  • Indeks chronometrażu można rzutować na HttpSysRequestTimingType, aby wiedzieć, co reprezentuje czas.
  • Wartość może wynosić 0, jeśli czas nie jest dostępny dla bieżącego żądania.
  • Wymaga Windows 10 w wersji 2004, Windows Server 2022 lub nowszej.
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 pobiera znacznik czasu dla podanego typu pomiaru czasu:

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 daje czas, który upłynął między dwoma określonymi punktami czasowymi:

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();

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek reset.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 11 kompilacji 22000 lub nowszej Windows Server 2022 kompilacji 20348 lub nowszej.
  • Połączenie TLS 1.2 lub nowsze.

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że trailery są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje podaną nazwę trailera do nagłówka odpowiedzi Trailer. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza trailer.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

Tracing

Aby uzyskać informacje na temat pobierania śladów z HTTP.sys, zobacz scenariusze zarządzania HTTP.sys.

Automatyczna eksmisja z puli pamięci

Pule pamięci używane przez Kestrel, IIS i HTTP.sys automatycznie usuwają bloki pamięci, gdy aplikacja jest bezczynna lub pod niskim obciążeniem. Funkcja jest uruchamiana automatycznie i nie musi być włączona ani skonfigurowana ręcznie.

W wersjach .NET starszych niż 10 pamięć przydzielona przez pulę pozostaje zarezerwowana, nawet jeśli nie jest używana. Ta funkcja automatycznego usuwania zmniejsza ogólne użycie pamięci i pomaga aplikacjom pozostać responsywnymi przy różnych obciążeniach.

Korzystanie z metryk puli pamięci

Domyślna pula pamięci używana przez implementacje serwera ASP.NET Core obejmuje metryki, których można użyć do monitorowania i analizowania wzorców użycia pamięci. Metryki są pod nazwą "Microsoft.AspNetCore.MemoryPool".

Aby uzyskać informacje o metrykach i sposobie ich używania, zobacz ASP.NET Core metrics.

Zarządzanie pulami pamięci

Oprócz efektywnego zarządzania pulami pamięci poprzez usuwanie niepotrzebnych bloków, ASP.NET Core zapewnia wbudowaną IMemoryPoolFactory i jej implementację. Dzięki iniekcji zależności implementacja jest dostępna dla aplikacji.

Poniższy przykład kodu przedstawia prostą usługę działającą w tle, która używa wbudowanej implementacji fabryki puli pamięci do tworzenia pul pamięci. Te pule korzystają z funkcji automatycznego eksmitowania:

public class MyBackgroundService : BackgroundService
{
    private readonly MemoryPool<byte> _memoryPool;

    public MyBackgroundService(IMemoryPoolFactory<byte> factory)
    {
        _memoryPool = factory.Create();
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                await Task.Delay(20, stoppingToken);
                // do work that needs memory
                // consider checking _memoryPool.MaxBufferSize
                var rented = _memoryPool.Rent(100);
                rented.Dispose();
            }
            catch (OperationCanceledException)
            {
                return;
            }
        }
    }
}

Aby użyć niestandardowej fabryki puli pamięci, utwórz klasę, która implementuje IMemoryPoolFactory i zarejestruj ją za pomocą iniekcji zależności, jak w poniższym przykładzie. Pule pamięci utworzone w ten sposób nie korzystają z funkcji automatycznego usuwania, chyba że implementujesz podobną logikę usuwania w fabryce dostosowanej.

services.AddSingleton<IMemoryPoolFactory<byte>,
CustomMemoryPoolFactory>();

public class CustomMemoryPoolFactory : IMemoryPoolFactory<byte>
{
    public MemoryPool<byte> Create()
    {
        // Return a custom MemoryPool implementation
        // or the default, as is shown here.
        return MemoryPool<byte>.Shared;
    }
}

Jeśli używasz puli pamięci, należy pamiętać o puli MaxBufferSize.

HTTP.sys jest serwerem sieci Web dla ASP.NET Core, który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Uwierzytelnianie Windows
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)

Obsługiwane wersje Windows:

  • Windows 7 lub nowsza
  • Windows Server 2008 R2 lub nowszy

Wyświetlanie lub pobieranie przykładowego kodu (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. Same usługi IIS są uruchamiane jako odbiornik HTTP na podstawie HTTP.sys.

Obsługa protokołu HTTP/2

Protokół HTTP/2 jest włączony dla aplikacji ASP.NET Core, gdy spełnione są następujące podstawowe wymagania:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W przyszłej wersji Windows będą dostępne flagi konfiguracji HTTP/2, w tym możliwość wyłączenia protokołu HTTP/2 z HTTP.sys.

Obsługa protokołu HTTP/3

Protokół HTTP/3 jest włączony dla aplikacji ASP.NET Core, gdy spełnione są następujące podstawowe wymagania:

  • Windows Server 2022/Windows 11 lub nowszy
  • Używane jest powiązanie URL https.
  • Ustawiono klucz rejestru EnableHttp3.

Poprzednie wersje kompilacji Windows 11 mogą wymagać użycia kompilacji Windows insider.

Protokół HTTP/3 jest wykrywany jako uaktualnienie z protokołu HTTP/1.1 lub HTTP/2 za pośrednictwem nagłówka alt-svc . Oznacza to, że pierwsze żądanie zwykle będzie używać protokołu HTTP/1.1 lub HTTP/2 przed przełączeniem do protokołu HTTP/3. Protokół Http.Sys nie dodaje automatycznie nagłówka alt-svc — musi zostać dodany przez aplikację. Poniższy kod to przykład oprogramowania pośredniczącego, który dodaje alt-svc nagłówek odpowiedzi.

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

Umieść poprzedni kod na początku potoku żądania.

Http.Sys obsługuje również wysyłanie komunikatu protokołu HTTP/2 AltSvc zamiast nagłówka odpowiedzi w celu powiadomienia klienta o dostępności protokołu HTTP/3. Zobacz klucz rejestru EnableAltSvc. Wymaga to powiązań netsh sslcert, które używają nazw hostów, a nie adresów IP.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje uwierzytelnianie do trybu jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę UseHttpSys rozszerzenia podczas kompilowania hosta, określając dowolną wymaganą metodę HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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>();
        });

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

Aby uzyskać więcej informacji na temat opcji HTTP.sys, zobacz HttpSysOptions.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. Ten limit nie wpływa na połączenia, które zostały uaktualnione, ponieważ są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy właściwość MaxRequestBodySize jest ustawiona jako tylko do odczytu, co oznacza, że jest za późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize żądanie, użyj polecenia 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();
    });
}

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybierz profil aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj polecenia cmdlet Windows Firewall lub New-NetFirewallRule polecenia cmdlet programu PowerShell w celu otwarcia portów zapory w celu umożliwienia ruchu do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobiste.

  4. Jeśli aplikacja jest wdrożeniem zależnym od framework, zainstaluj .NET, .NET Framework lub obie (jeśli aplikacja jest aplikacją .NET przeznaczoną dla platformy .NET).

    • .NET: jeśli aplikacja wymaga .NET, uzyskaj i uruchom instalator środowiska uruchomieniowego .NET z .NET Downloads. Nie instaluj pełnego zestawu SDK na serwerze.
    • .NET Framework: jeśli aplikacja wymaga platformy .NET Framework, zobacz przewodnik instalacji platformy .NET Framework. Zainstaluj wymaganą platformę .NET Framework. Instalator najnowszego .NET Framework jest dostępny na stronie .NET Downloads.

    Jeśli aplikacja jest wdrożeniem niezależnym, zawiera środowisko uruchomieniowe. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 443:

    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>();
            });
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes nadpisują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys używa formatów ciągów UrlPrefix interfejsu API serwera HTTP.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

  6. Wstępnie zarejestrować prefiksy adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: w pełni kwalifikowany ujednolicony lokalizator zasobów (URL). Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś, w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup> z identyfikatorem GUID, który utworzyłeś:

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

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator losowego identyfikatora appid GUID w trybie online zapewnia wartość .
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uprawnienia administratora nie są wymagane do uruchamiania aplikacji podczas tworzenia powiązania z hostem lokalnym przy użyciu protokołu HTTP (a nie HTTPS) z numerem portu większym niż 1024. W przypadku innych konfiguracji (na przykład przy użyciu lokalnego adresu IP lub powiązania z portem 443) uruchom aplikację z uprawnieniami administratora.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek reset.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 11 kompilacji 22000 lub nowszej Windows Server 2022 kompilacji 20348 lub nowszej.
  • Połączenie TLS 1.2 lub nowsze.

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że trailery są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje podaną nazwę trailera do nagłówka odpowiedzi Trailer. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza trailer.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

HTTP.sys jest serwerem sieci Web dla ASP.NET Core, który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Uwierzytelnianie Windows
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)

Obsługiwane wersje Windows:

  • Windows 7 lub nowsza
  • Windows Server 2008 R2 lub nowszy

Wyświetlanie lub pobieranie przykładowego kodu (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. Same usługi IIS są uruchamiane jako odbiornik HTTP na podstawie HTTP.sys.

Obsługa protokołu HTTP/2

Protokół HTTP/2 jest włączony dla aplikacji ASP.NET Core, jeśli spełnione są następujące podstawowe wymagania:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W przyszłej wersji Windows będą dostępne flagi konfiguracji HTTP/2, w tym możliwość wyłączenia protokołu HTTP/2 z HTTP.sys.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje uwierzytelnianie do trybu jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę UseHttpSys rozszerzenia podczas kompilowania hosta, określając dowolną wymaganą metodę HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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>();
        });

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

Opcje HTTP.sys

Property Description Default
AllowSynchronousIO Określ, czy dane wejściowe/wyjściowe synchroniczne są dozwolone dla parametrów HttpContext.Request.Body i HttpContext.Response.Body. false
Authentication.AllowAnonymous Zezwalaj na żądania anonimowe. true
Authentication.Schemes Określ dozwolone schematy uwierzytelniania. Może być modyfikowany w dowolnej chwili przed usunięciem nasłuchiwacza. Wartości są dostarczane przez wyliczenie AuthenticationSchemes: Basic, Kerberos, Negotiate, None i NTLM. None
EnableResponseCaching Spróbuj buforowania trybu jądra dla odpowiedzi z odpowiednimi nagłówkami. Odpowiedź może nie zawierać nagłówków Set-Cookie, Vary lub Pragma. Musi zawierać nagłówek Cache-Control, który jest public oraz wartość shared-max-age albo max-age, lub nagłówek Expires. true
Http503Verbosity Zachowanie HTTP.sys podczas odrzucania żądań z powodu warunków ograniczania przepustowości. Http503VerbosityLevel.
Podstawowy
MaxAccepts Maksymalna liczba jednoczesnych akceptacji. 5 × Środowisko.
LiczbaProcesorów
MaxConnections Maksymalna liczba współbieżnych połączeń do zaakceptowania. Użyj -1 do oznaczenia nieskończoności. Użyj null do użycia ustawienia maszyny na poziomie systemu. null
(machine-wide
setting)
MaxRequestBodySize Zobacz sekcję MaxRequestBodySize . 30000000 bajtów
(~28,6 MB)
RequestQueueLimit Maksymalna liczba żądań, które można kolejkować. 1000
RequestQueueMode Wskazuje to, czy serwer jest odpowiedzialny za tworzenie i konfigurowanie kolejki żądań, czy też należy dołączyć go do istniejącej kolejki.
Większość dostępnych opcji konfiguracji nie ma zastosowania przy dołączaniu do istniejącej kolejki.
RequestQueueMode.Create
RequestQueueName Nazwa kolejki żądań HTTP.sys. null (Kolejka anonimowa)
ThrowWriteExceptions Wskaż, czy w przypadku niepowodzenia zapisu treści odpowiedzi z powodu rozłączenia klienta, powinny być zgłaszane wyjątki, czy proces powinien zakończyć się normalnie. false
(ukończone normalnie)
Timeouts Uwidocznij konfigurację HTTP.sys TimeoutManager , która może być również skonfigurowana w rejestrze. Skorzystaj z linków interfejsu API, aby dowiedzieć się więcej o każdym ustawieniu, w tym wartościach domyślnych:
UrlPrefixes Określ UrlPrefixCollection, aby zarejestrować w HTTP.sys. Najbardziej przydatna jest funkcja UrlPrefixCollection.Add, która służy do dodawania prefiksu do kolekcji. Mogą one być modyfikowane w dowolnym momencie przed zakończeniem używania nasłuchiwacza.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. Ten limit nie wpływa na połączenia, które zostały uaktualnione, ponieważ są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy właściwość MaxRequestBodySize jest ustawiona jako tylko do odczytu, co oznacza, że jest za późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize żądanie, użyj polecenia 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();
    });
}

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybierz profil aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj polecenia cmdlet Windows Firewall lub New-NetFirewallRule polecenia cmdlet programu PowerShell w celu otwarcia portów zapory w celu umożliwienia ruchu do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobiste.

  4. Jeśli aplikacja jest wdrożeniem zależnym od framework, zainstaluj .NET, .NET Framework lub obie (jeśli aplikacja jest aplikacją .NET przeznaczoną dla platformy .NET).

    • .NET: jeśli aplikacja wymaga .NET, uzyskaj i uruchom instalator środowiska uruchomieniowego .NET z .NET Downloads. Nie instaluj pełnego zestawu SDK na serwerze.
    • .NET Framework: jeśli aplikacja wymaga platformy .NET Framework, zobacz przewodnik instalacji platformy .NET Framework. Zainstaluj wymaganą platformę .NET Framework. Instalator najnowszego .NET Framework jest dostępny na stronie .NET Downloads.

    Jeśli aplikacja jest wdrożeniem niezależnym, zawiera środowisko uruchomieniowe. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 443:

    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>();
            });
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes nadpisują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys używa formatów ciągów UrlPrefix interfejsu API serwera HTTP.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

  6. Wstępnie zarejestrować prefiksy adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: w pełni kwalifikowany ujednolicony lokalizator zasobów (URL). Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś, w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup> z identyfikatorem GUID, który utworzyłeś:

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

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator losowego identyfikatora appid GUID w trybie online zapewnia wartość .
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uprawnienia administratora nie są wymagane do uruchamiania aplikacji podczas tworzenia powiązania z hostem lokalnym przy użyciu protokołu HTTP (a nie HTTPS) z numerem portu większym niż 1024. W przypadku innych konfiguracji (na przykład przy użyciu lokalnego adresu IP lub powiązania z portem 443) uruchom aplikację z uprawnieniami administratora.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek reset.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 10, kompilacja systemu operacyjnego 19041.508 lub nowsza
  • Połączenie TLS 1.2 lub nowsze

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że trailery są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje podaną nazwę trailera do nagłówka odpowiedzi Trailer. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza trailer.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

HTTP.sys jest serwerem sieci Web dla ASP.NET Core, który działa tylko w Windows. HTTP.sys jest alternatywą dla Kestrel serwera i oferuje niektóre funkcje, które Kestrel nie zapewniają.

Important

HTTP.sys nie jest zgodna z modułem ASP.NET Core i nie może być używana z usługami IIS lub IIS Express.

HTTP.sys obsługuje następujące funkcje:

  • Uwierzytelnianie Windows
  • Udostępnianie portów
  • Protokół HTTPS z siecią SNI
  • Protokół HTTP/2 za pośrednictwem protokołu TLS (Windows 10 lub nowszy)
  • Protokół HTTP/3 za pośrednictwem protokołu TLS (Windows 11 lub nowszy)
  • Bezpośrednia transmisja plików
  • Buforowanie odpowiedzi
  • WebSockets (Windows 8 lub nowsze)
  • Dostosowywalne deskryptory zabezpieczeń

Obsługiwane wersje Windows:

  • Windows 7 lub nowsza
  • Windows Server 2008 R2 lub nowszy

Wyświetlanie lub pobieranie przykładowego kodu (jak pobrać)

Kiedy należy używać HTTP.sys

HTTP.sys jest przydatna w przypadku wdrożeń, w których:

  • Istnieje potrzeba uwidocznienia serwera bezpośrednio w Internecie bez korzystania z usług IIS.

    HTTP.sys komunikuje się bezpośrednio z Internetem

  • Wdrożenie wewnętrzne wymaga funkcji niedostępnej w programie Kestrel. Aby uzyskać więcej informacji, zobacz Kestrel vs. HTTP.sys

    HTTP.sys komunikuje się bezpośrednio z siecią wewnętrzną

HTTP.sys to dojrzała technologia, która chroni przed wieloma typami ataków i zapewnia niezawodność, bezpieczeństwo i skalowalność pełnoekranowego serwera internetowego. Same usługi IIS są uruchamiane jako odbiornik HTTP na podstawie HTTP.sys.

Obsługa protokołu HTTP/2

Protokół HTTP/2 jest włączony dla aplikacji ASP.NET Core, gdy spełnione są następujące podstawowe wymagania:

Jeśli połączenie HTTP/2 zostanie nawiązane, httpRequest.Protocol zgłasza HTTP/2.

Protokół HTTP/2 jest domyślnie włączony. Jeśli połączenie HTTP/2 nie zostanie nawiązane, połączenie powróci do protokołu HTTP/1.1. W przyszłej wersji Windows będą dostępne flagi konfiguracji HTTP/2, w tym możliwość wyłączenia protokołu HTTP/2 z HTTP.sys.

Obsługa protokołu HTTP/3

Protokół HTTP/3 jest włączony dla aplikacji ASP.NET Core, gdy spełnione są następujące podstawowe wymagania:

  • Windows Server 2022/Windows 11 lub nowszy
  • Używane jest powiązanie URL https.
  • Ustawiono klucz rejestru EnableHttp3.

Poprzednie wersje kompilacji Windows 11 mogą wymagać użycia kompilacji Windows insider.

Protokół HTTP/3 jest wykrywany jako uaktualnienie z protokołu HTTP/1.1 lub HTTP/2 za pośrednictwem nagłówka alt-svc . Oznacza to, że pierwsze żądanie zwykle będzie używać protokołu HTTP/1.1 lub HTTP/2 przed przełączeniem do protokołu HTTP/3. Protokół Http.Sys nie dodaje automatycznie nagłówka alt-svc — musi zostać dodany przez aplikację. Poniższy kod to przykład oprogramowania pośredniczącego, który dodaje alt-svc nagłówek odpowiedzi.

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

Umieść poprzedni kod na początku potoku żądania.

Http.Sys obsługuje również wysyłanie komunikatu protokołu HTTP/2 AltSvc zamiast nagłówka odpowiedzi w celu powiadomienia klienta o dostępności protokołu HTTP/3. Zobacz klucz rejestru EnableAltSvc. Wymaga to powiązań netsh sslcert, które używają nazw hostów, a nie adresów IP.

Uwierzytelnianie w trybie jądra przy użyciu protokołu Kerberos

HTTP.sys deleguje uwierzytelnianie do trybu jądra przy użyciu protokołu uwierzytelniania Kerberos. Uwierzytelnianie w trybie użytkownika nie jest obsługiwane w przypadku protokołu Kerberos i HTTP.sys. Konto komputera musi służyć do odszyfrowywania tokenu/biletu Protokołu Kerberos uzyskanego z Active Directory i przekazywanego przez klienta do serwera w celu uwierzytelnienia użytkownika. Zarejestruj nazwę główną usługi (SPN) dla hosta, a nie użytkownika aplikacji.

Włącz wzmacnianie zabezpieczeń tokenu powiązania kanału (CBT)

Tokeny wiązania kanału (CBT) wiążą uwierzytelnianie Windows z bazowym kanałem TLS, co pomaga ograniczyć ataki przekazywania NTLM i ataki typu man-in-the-middle. W przypadku punktów końcowych HTTPS, które używają uwierzytelniania Windows z HTTP.sys, możesz wyrazić zgodę na utwardzenie CBT, ustawiając przełącznik Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening AppContext na true.

Włącz przełącznik w pliku projektu runtimeconfig.template.json :

{
  "configProperties": {
    "Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening": true
  }
}

Możesz też programowo ustawić przełącznik przed utworzeniem hosta w Program.cs:

AppContext.SetSwitch("Microsoft.AspNetCore.Server.HttpSys.EnableCBTHardening", true);

Warning

Wzmocnienie zabezpieczeń CBT jest domyślnie wyłączone. Włączenie tego może spowodować niepowodzenie uwierzytelniania Windows dla klientów lub proxy, które nie obsługują wiązania kanału. Dokładnie przetestuj w swoim środowisku przed włączeniem w środowisku produkcyjnym.

Obsługa buforowania odpowiedzi w trybie jądra

W niektórych scenariuszach duże ilości małych zapisów z dużym opóźnieniem mogą spowodować znaczny wpływ na wydajność.HTTP.sys Ten wpływ jest spowodowany brakiem Pipe buforu w implementacji HTTP.sys . Aby zwiększyć wydajność w tych scenariuszach, obsługa buforowania odpowiedzi jest uwzględniana w systemie HTTP.sys. Włącz buforowanie, ustawiając wartość HttpSysOptions.EnableKernelResponseBuffering na true. Buforowanie odpowiedzi powinno być włączone przez aplikację, która wykonuje synchroniczne operacje we/wy lub asynchroniczne operacje we/wy bez więcej niż jednego zaległego zapisu naraz. W tych scenariuszach buforowanie odpowiedzi może znacznie zwiększyć przepływność w przypadku połączeń o dużym opóźnieniu.

Aplikacje, które korzystają z asynchronicznych operacji we/wy i mogą mieć więcej niż jeden nieukończony zapis jednocześnie, nie powinny używać tej flagi. Włączenie tej flagi może spowodować wyższe użycie procesora CPU i pamięci przez HTTP.Sys.

Jak używać HTTP.sys

Konfigurowanie aplikacji ASP.NET Core do używania HTTP.sys

Wywołaj metodę UseHttpSys rozszerzenia podczas kompilowania hosta, określając dowolną wymaganą metodę HttpSysOptions. Poniższy przykład ustawia opcje na wartości domyślne:

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();

Dodatkowa konfiguracja HTTP.sys jest obsługiwana za pośrednictwem ustawień rejestru.

Aby uzyskać więcej informacji na temat opcji HTTP.sys, zobacz HttpSysOptions.

MaxRequestBodySize

Maksymalny dozwolony rozmiar dowolnej treści żądania w bajtach. Jeśli ustawiono wartość null, maksymalny rozmiar treści żądania jest nieograniczony. Ten limit nie wpływa na połączenia, które zostały uaktualnione, ponieważ są zawsze nieograniczone.

Zalecaną metodą zastąpienia limitu w aplikacji MVC ASP.NET Core dla pojedynczego IActionResult jest użycie atrybutu RequestSizeLimitAttribute w metodzie akcji:

[RequestSizeLimit(100000000)]
public IActionResult MyActionMethod()

Zgłaszany jest wyjątek, jeśli aplikacja próbuje skonfigurować limit żądania po rozpoczęciu odczytywania żądania przez aplikację. Właściwość IsReadOnly może służyć do wskazania, czy właściwość MaxRequestBodySize jest ustawiona jako tylko do odczytu, co oznacza, że jest za późno na skonfigurowanie limitu.

Jeśli aplikacja powinna zastąpić MaxRequestBodySize żądanie, użyj polecenia 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);
});

Jeśli używasz Visual Studio, upewnij się, że aplikacja nie jest skonfigurowana do uruchamiania usług IIS lub IIS Express.

W Visual Studio domyślnym profilem uruchamiania jest usługa IIS Express. Aby uruchomić projekt jako aplikację konsolową, ręcznie zmień wybrany profil, jak pokazano na poniższym zrzucie ekranu:

Wybieranie profilu aplikacji konsolowej

Konfigurowanie Windows Server

  1. Określ porty do otwarcia dla aplikacji i użyj polecenia cmdlet Windows Firewall lub New-NetFirewallRule polecenia cmdlet programu PowerShell w celu otwarcia portów zapory w celu umożliwienia ruchu do HTTP.sys. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  2. Podczas wdrażania na maszynie wirtualnej Azure otwórz porty w Network Security Group. W poniższych poleceniach i konfiguracji aplikacji jest używany port 443.

  3. W razie potrzeby uzyskaj i zainstaluj certyfikaty X.509.

    W Windows utwórz certyfikaty z podpisem własnym przy użyciu polecenia cmdlet New-SelfSignedCertificate programu PowerShell. Aby zapoznać się z nieobsługiwanym przykładem, zobacz UpdateIISExpressSSLForChrome.ps1.

    Zainstaluj certyfikaty z podpisem własnym lub z podpisem urzędu certyfikacji w magazynie Local Machine>Osobiste.

  4. Jeśli aplikacja jest wdrożeniem zależnym od framework, zainstaluj .NET, .NET Framework lub obie (jeśli aplikacja jest aplikacją .NET przeznaczoną dla platformy .NET).

    • .NET: jeśli aplikacja wymaga .NET, uzyskaj i uruchom instalator środowiska uruchomieniowego .NET z .NET Downloads. Nie instaluj pełnego zestawu SDK na serwerze.
    • .NET Framework: jeśli aplikacja wymaga platformy .NET Framework, zobacz przewodnik instalacji platformy .NET Framework. Zainstaluj wymaganą platformę .NET Framework. Instalator najnowszego .NET Framework jest dostępny na stronie .NET Downloads.

    Jeśli aplikacja jest wdrożeniem niezależnym, zawiera środowisko uruchomieniowe. Na serwerze nie jest wymagana instalacja platformy.

  5. Skonfiguruj adresy URL i porty w aplikacji.

    Domyślnie ASP.NET Core wiąże się z http://localhost:5000. Aby skonfigurować prefiksy adresów URL i porty, opcje obejmują:

    • UseUrls
    • urls argument wiersza polecenia
    • ASPNETCORE_URLS zmienna środowiskowa
    • UrlPrefixes

    W poniższym przykładzie kodu pokazano, jak używać UrlPrefixes z lokalnym adresem 10.0.0.4 IP serwera na porcie 443:

    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();
    

    UrlPrefixes Zaletą jest to, że komunikat o błędzie jest generowany natychmiast dla nieprawidłowo sformatowanych prefiksów.

    Ustawienia w UrlPrefixes nadpisują ustawienia UseUrls/urls/ASPNETCORE_URLS. W związku z tym zaletą zmiennej środowiskowej UseUrls, urlsi ASPNETCORE_URLS jest to, że łatwiej jest przełączać się między Kestrel i HTTP.sys.

    HTTP.sys rozpoznaje dwa typy symboli wieloznacznych w prefiksach adresów URL:

    • * jest słabym powiązaniem, znanym również jako powiązanie rezerwowe. Jeśli prefiks adresu URL to http://*:5000, a coś innego jest powiązane z portem 5000, to powiązanie nie będzie używane.
    • + jest silnym powiązaniem adresu. Jeśli prefiks adresu URL to http://+:5000, to powiązanie będzie używane przed innymi powiązaniami portu 5000.

    Aby uzyskać więcej informacji, zobacz Ciągi prefiksu URL.

    Warning

    Nie należy używać powiązań z symbolami wieloznacznymi najwyższego poziomu (http://*:80/ i http://+:80). Powiązania z symbolami wieloznacznymi najwyższego poziomu tworzą luki w zabezpieczeniach aplikacji. Dotyczy to zarówno silnych, jak i słabych symboli wieloznacznych. Użyj jawnych nazw hostów lub adresów IP, a nie symboli wieloznacznych. Powiązanie wieloznaczne poddomeny (na przykład *.mysub.com) nie jest zagrożeniem bezpieczeństwa, jeśli kontrolujesz całą domenę nadrzędną (w przeciwieństwie do *.com, która jest podatna na zagrożenia). Aby uzyskać więcej informacji, zobacz RFC 9110: Sekcja 7.2: Host i :authority.

    Większość konfiguracji aplikacji i kontenerów definiuje tylko port nasłuchujący, taki jak port 80, bez określania innych ograniczeń, takich jak host lub ścieżka. HTTP_PORTS i HTTPS_PORTS to klucze konfiguracji, które określają porty nasłuchiwania dla Kestrel serwerów i HTTP.sys. Klucze można określić jako zmienne środowiskowe zdefiniowane przy użyciu prefiksów DOTNET_ lub ASPNETCORE_, albo ustawić je bezpośrednio za pomocą dowolnego innego źródła konfiguracji, takiego jak plik appsettings.json. Każda konfiguracja to rozdzielana średnikami lista wartości portów, jak pokazano w poniższym przykładzie:

    ASPNETCORE_HTTP_PORTS=80;8080
    ASPNETCORE_HTTPS_PORTS=443;8081
    

    Konfiguracja w przykładzie jest skrócona dla następującej specyfikacji, która definiuje schemat (HTTP lub HTTPS) i dowolny host lub adres IP:

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

    Klucze konfiguracji HTTP_PORTS i HTTPS_PORTS mają niższy priorytet. Jeśli inne adresy URL lub wartości są ustawiane bezpośrednio w kodzie, mogą zastąpić klucze konfiguracji. Skonfiguruj certyfikaty oddzielnie przy użyciu mechaniki specyficznej dla serwera dla protokołu HTTPS.

    Note

    Nie należy mylić klucza konfiguracji HTTPS_PORTS i zmiennej środowiskowej ASPNETCORE_HTTPS_PORTS, które ustawiają porty dla konfiguracji punktów końcowych Kestrel/HTTP.sys, z kluczem konfiguracji HTTPS_PORT i zmienną środowiskową ASPNETCORE_HTTPS_PORT, które ustawiają port dla middleware przekierowania HTTPS.

    Te klucze konfiguracji są równoważne powiązaniom symboli wieloznacznych najwyższego poziomu. Są one wygodne w środowiskach programistycznych i kontenerowych, ale unikaj symboli wieloznacznych podczas uruchamiania na maszynie, która może również hostować inne usługi.

  6. Wstępnie zarejestrować prefiksy adresów URL na serwerze.

    Wbudowane narzędzie do konfigurowania HTTP.sys jest netsh.exe. netsh.exe służy do rezerwowania prefiksów adresów URL i przypisywania certyfikatów X.509. Narzędzie wymaga uprawnień administratora.

    Użyj narzędzia netsh.exe, aby zarejestrować adresy URL aplikacji:

    netsh http add urlacl url=<URL> user=<USER>
    
    • <URL>: w pełni kwalifikowany ujednolicony lokalizator zasobów (URL). Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowej nazwy hosta lub lokalnego adresu IP. Adres URL musi zawierać ukośnik końcowy.
    • <USER>: określa nazwę użytkownika lub grupy użytkowników.

    W poniższym przykładzie lokalny adres IP serwera to 10.0.0.4:

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

    Po zarejestrowaniu adresu URL narzędzie odpowiada URL reservation successfully added.

    Aby usunąć zarejestrowany adres URL, użyj delete urlacl polecenia :

    netsh http delete urlacl url=<URL>
    
  7. Zarejestruj certyfikaty X.509 na serwerze.

    Użyj narzędzia netsh.exe, aby zarejestrować certyfikaty dla aplikacji:

    netsh http add sslcert ipport=<IP>:<PORT> certhash=<THUMBPRINT> appid="{<GUID>}"
    
    • <IP>: określa lokalny adres IP powiązania. Nie używaj wiązań z symbolami wieloznacznymi. Użyj prawidłowego adresu IP.
    • <PORT>: określa port powiązania.
    • <THUMBPRINT>: odcisk palca certyfikatu X.509.
    • <GUID>: identyfikator GUID wygenerowany przez dewelopera reprezentujący aplikację do celów informacyjnych.

    Do celów referencyjnych zapisz identyfikator GUID w aplikacji jako tag pakietu:

    • W Visual Studio:
      • Otwórz właściwości projektu aplikacji, klikając prawym przyciskiem myszy aplikację w Eksplorator rozwiązań i wybierając pozycję Właściwości.
      • Wybierz kartę Pakiet .
      • Wprowadź identyfikator GUID, który utworzyłeś, w polu Tagi.
    • Jeśli nie używasz Visual Studio:
      • Otwórz plik projektu aplikacji.

      • Dodaj właściwość <PackageTags> do nowej lub istniejącej <PropertyGroup> z identyfikatorem GUID, który utworzyłeś:

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

    W poniższym przykładzie:

    • Lokalny adres IP serwera to 10.0.0.4.
    • Generator losowego identyfikatora appid GUID w trybie online zapewnia wartość .
    netsh http add sslcert 
        ipport=10.0.0.4:443 
        certhash=b66ee04419d4ee37464ab8785ff02449980eae10 
        appid="{00001111-aaaa-2222-bbbb-3333cccc4444}"
    

    Po zarejestrowaniu certyfikatu narzędzie odpowiada za pomocą SSL Certificate successfully added.

    Aby usunąć rejestrację certyfikatu, użyj delete sslcert polecenia :

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

    Dokumentacja referencyjna netsh.exe:

  8. Uruchom aplikację.

    Uprawnienia administratora nie są wymagane do uruchamiania aplikacji podczas tworzenia powiązania z hostem lokalnym przy użyciu protokołu HTTP (a nie HTTPS) z numerem portu większym niż 1024. W przypadku innych konfiguracji (na przykład przy użyciu lokalnego adresu IP lub powiązania z portem 443) uruchom aplikację z uprawnieniami administratora.

    Aplikacja odpowiada na publiczny adres IP serwera. W tym przykładzie serwer jest osiągany z Internetu pod jego publicznym adresem IP .104.214.79.47

    W tym przykładzie używany jest certyfikat dewelopera. Strona ładuje się bezpiecznie po ominięciu ostrzeżenia przeglądarki dotyczącego niezaufanego certyfikatu.

    Okno przeglądarki z załadowaną stroną indeksu aplikacji

Scenariusze dotyczące serwera proxy i modułu równoważenia obciążenia

W przypadku aplikacji hostowanych przez HTTP.sys, które współdziałają z żądaniami z Internetu lub sieci firmowej, może być wymagana dodatkowa konfiguracja w przypadku hostowania serwerów proxy i modułów równoważenia obciążenia. Aby uzyskać więcej informacji, zobacz Konfigurowanie ASP.NET Core do pracy z serwerami proxy i modułami równoważenia obciążenia.

Uzyskiwanie szczegółowych informacji o chronometrażu za pomocą funkcji IHttpSysRequestTimingFeature

IHttpSysRequestTimingFeature zawiera szczegółowe informacje o chronometrażu dla żądań:

  • Znaczniki czasu są uzyskiwane przy użyciu elementu QueryPerformanceCounter.
  • Częstotliwość sygnatury czasowej można uzyskać za pośrednictwem metody QueryPerformanceFrequency.
  • Indeks chronometrażu można rzutować na HttpSysRequestTimingType, aby wiedzieć, co reprezentuje czas.
  • Wartość może wynosić 0, jeśli czas nie jest dostępny dla bieżącego żądania.
  • Wymaga Windows 10 w wersji 2004, Windows Server 2022 lub nowszej.
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 pobiera znacznik czasu dla podanego typu pomiaru czasu:

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](/dotnet/api/microsoft.aspnetcore.server.httpsys.ihttpsysrequesttimingfeature.trygetelapsedtime) zwraca czas, który upłynął między dwoma określonymi pomiarami.

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();

Zaawansowane funkcje HTTP/2 do obsługi gRPC

Dodatkowe funkcje HTTP/2 w HTTP.sys obsługują gRPC, w tym obsługę trailerów odpowiedzi i wysyłanie ramek reset.

Wymagania dotyczące uruchamiania usługi gRPC z HTTP.sys:

  • Windows 11 kompilacji 22000 lub nowszej Windows Server 2022 kompilacji 20348 lub nowszej.
  • Połączenie TLS 1.2 lub nowsze.

Trailers

Trailery HTTP są podobne do nagłówków HTTP, z tym wyjątkiem, że są wysyłane po wysłaniu treści odpowiedzi. W przypadku usług IIS i HTTP.sys obsługiwane są tylko przyczepy odpowiedzi HTTP/2.

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

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

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

W poprzednim przykładowym kodzie:

  • SupportsTrailers zapewnia, że trailery są obsługiwane w odpowiedzi.
  • DeclareTrailer dodaje podaną nazwę trailera do nagłówka odpowiedzi Trailer. Deklarowanie przyczep odpowiedzi jest opcjonalne, ale zalecane. Jeśli DeclareTrailer jest wywoływana, musi to być przed wysłaniem nagłówków odpowiedzi.
  • AppendTrailer dołącza trailer.

Reset

Resetowanie umożliwia serwerowi zresetowanie żądania HTTP/2 z określonym kodem błędu. Żądanie resetowania jest uznawane za przerwane.

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

Reset w poprzednim przykładzie kodu określa kod błędu INTERNAL_ERROR . Aby uzyskać więcej informacji na temat kodów błędów HTTP/2, odwiedź sekcję kod błędu specyfikacji HTTP/2.

Tracing

Aby uzyskać informacje na temat pobierania śladów z HTTP.sys, zobacz scenariusze zarządzania HTTP.sys.

Note

Linki w dokumentacji do referencyjnego kodu źródłowego platformy .NET zwykle otwierają domyślną gałąź repozytorium, która odzwierciedla bieżący stan prac rozwojowych nad następną wersją platformy .NET. Aby wybrać tag dla określonej wersji, użyj listy rozwijanej Przełącz gałęzie lub tagi.