From 477f975fe884b4c7409f272bf2bfff9f4d1bbbf4 Mon Sep 17 00:00:00 2001 From: John Zabroski Date: Wed, 11 Jun 2025 12:24:20 -0400 Subject: [PATCH 1/4] Enhance instructions to Test CORS (#35593) --- aspnetcore/security/cors.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/aspnetcore/security/cors.md b/aspnetcore/security/cors.md index d27cc7ce1a64..c4394e453c35 100644 --- a/aspnetcore/security/cors.md +++ b/aspnetcore/security/cors.md @@ -546,6 +546,9 @@ The [sample download](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnet > [!WARNING] > `WithOrigins("https://localhost:");` should only be used for testing a sample app similar to the [download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/live/aspnetcore/security/cors/8.0sample/Cors). +> [!NOTE] +> If you're using `launchSettings.json` in Visual Studio or [configuring C# debug settings in VS Code](https://code.visualstudio.com/docs/csharp/debugger-settings), and using IIS Express to debug locally, ensure that you've configured IIS Express for `"anonymousAuthentication": true`. When `"anonymousAuthentication"` is `false`, the ASP.NET Core web environment host will not see any preflight requests. In particular, if you're using NTLM authentication (`"windowsAuthentication": true`), the first step of the NTLM challenge-response is to send the web browser a 401 challenge, which can make it challenging to verify your preflight route is configured correctly. + The following `ValuesController` provides the endpoints for testing: [!code-csharp[](~/security/cors/8.0sample/Cors/Web2API/Controllers/ValuesController.cs?name=snippet)] From bf56fffe22fb7d4cd5281822676377457875c488 Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Thu, 12 Jun 2025 08:22:52 -0400 Subject: [PATCH 2/4] Focus Identity on BWAs (#35618) --- .../security/authentication/identity.md | 114 +++++++++++++++--- 1 file changed, 100 insertions(+), 14 deletions(-) diff --git a/aspnetcore/security/authentication/identity.md b/aspnetcore/security/authentication/identity.md index 2d415b78e8c5..af61fed90a0a 100644 --- a/aspnetcore/security/authentication/identity.md +++ b/aspnetcore/security/authentication/identity.md @@ -11,8 +11,6 @@ uid: security/authentication/identity :::moniker range=">= aspnetcore-8.0" -By [Rick Anderson](https://twitter.com/RickAndMSFT) - ASP.NET Core Identity: * Is an API that supports user interface (UI) login functionality. @@ -28,6 +26,8 @@ Identity is typically configured using a SQL Server database to store user names In this topic, you learn how to use Identity to register, log in, and log out a user. Note: the templates treat username and email as the same for users. For more detailed instructions about creating apps that use Identity, see [Next Steps](#next). +For more information on Identity in Blazor apps, see and the articles that follow it in the Blazor documentation. + ASP.NET Core Identity isn't related to the [Microsoft identity platform](/azure/active-directory/develop/). Microsoft identity platform is: * An evolution of the Azure Active Directory (Azure AD) developer platform. @@ -39,34 +39,119 @@ ASP.NET Core Identity isn't related to the [Microsoft identity platform](/azure/ -## Create a Web app with authentication +## Create a Blazor Web App with authentication + +Create an ASP.NET Core Blazor Web App project with Individual Accounts. -Create an ASP.NET Core Web Application project with Individual Accounts. +> [!NOTE] +> For a Razor Pages experience, see the [Create a Razor Pages app with authentication](#create-a-razor-pages-app-with-authentication) section. +> +> For an MVC experience, see the [Create an MVC app with authentication](#create-an-mvc-app-with-authentication) section. # [Visual Studio](#tab/visual-studio) -* Select the **ASP.NET Core Web App** template. Name the project **WebApp1** to have the same namespace as the project download. Click **OK**. -* In the **Authentication type** input, select **Individual Accounts**. +* Select the **Blazor Web App** template. Select **Next**. +* Make the following selections: + * **Authentication type**: **Individual Accounts** + * **Interactive render mode**: **Server** + * **Interactivity Location**: **Global** +* Select **Create**. # [.NET CLI](#tab/net-cli) ```dotnetcli -dotnet new webapp --auth Individual -o WebApp1 +dotnet new blazor -au Individual -o BlazorApp1 ``` -The preceding command creates a Razor web app using SQLite. To create the web app with LocalDB, run the following command: +The `-o|--output` option creates a folder for the app and sets the app name/namespace. + +The preceding command creates a Blazor Web App using SQLite. To create the app with LocalDB, run the following command: ```dotnetcli -dotnet new webapp --auth Individual -uld -o WebApp1 +dotnet new blazor -au Individual -uld -o BlazorApp1 ``` --- -The generated project provides [ASP.NET Core Identity](xref:security/authentication/identity) as a [Razor class library](xref:razor-pages/ui-class). The Identity Razor class library exposes endpoints with the `Identity` area. For example: +The generated project includes Identity Razor components. The components are found in the `Components/Account` folder. For example: + +* `/Components/Account/Pages/Register` +* `/Components/Account/Pages/Login` +* `/Components/Account/Pages/Manage/ChangePassword` + +Identity Razor components are described individually in the documentation for specific use cases and are subject to change each release. When you generate a Blazor Web App with Individual Accounts, Identity Razor components are included in the generated project. The Identity Razor components can also be inspected in the [Blazor project template in the ASP.NET Core reference source (`dotnet/aspnetcore` GitHub repository)](https://github.com/dotnet/aspnetcore/tree/main/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWeb-CSharp/Components/Account). + +[!INCLUDE[](~/includes/aspnetcore-repo-ref-source-links.md)] + +For more information, see and the articles that follow it in the Blazor documentation. Most of the articles in the *Security and Identity* area of the main ASP.NET Core documentation set apply to Blazor apps. However, the Blazor documentation set contains articles and guidance that supersedes or adds information. We recommend studying the general ASP.NET Core documentation set first, followed by accessing the articles in the Blazor *Security and Identity* documentation. + +## Create a Razor Pages app with authentication + +Create an ASP.NET Core Web Application (Razor Pages) project with Individual Accounts. + +# [Visual Studio](#tab/visual-studio) + +* Select the **ASP.NET Core Web App (Razor Pages)** template. Select **Next**. +* For **Authentication type**, select **Individual Accounts**. +* Select **Create**. + +# [.NET CLI](#tab/net-cli) + +```dotnetcli +dotnet new webapp -au Individual -o WebApp1 +``` + +The `-o|--output` option creates a folder for the app and sets the app name/namespace. + +The preceding command creates a Razor Pages app using SQLite. To create the app with LocalDB, run the following command: + +```dotnetcli +dotnet new webapp -au Individual -uld -o WebApp1 +``` + +--- + +The generated project provides [ASP.NET Core Identity](xref:security/authentication/identity) as a [Razor class library (RCL)](xref:razor-pages/ui-class). The Identity Razor class library exposes endpoints with the `Identity` area. For example: + +* `Areas/Identity/Pages/Account/Register` +* `Areas/Identity/Pages/Account/Login` +* `Areas/Identity/Pages/Account/Manage/ChangePassword` + +Pages are described individually in the documentation for specific use cases and are subject to change each release. To view all of the pages in the RCL, see the [ASP.NET Core reference source (`dotnet/aspnetcore` GitHub repository, `Identity/UI/src/Areas/Identity/Pages` folder)](https://github.com/dotnet/aspnetcore/tree/main/src/Identity/UI/src/Areas/Identity/Pages). You can *scaffold* individual pages or all of the pages into the app. For more information, see . + +## Create an MVC app with authentication + +Create an ASP.NET Core MVC project with Individual Accounts. + +# [Visual Studio](#tab/visual-studio) + +* Select the **ASP.NET Core Web App (Model-View-Controller)** template. Select **Next**. +* For **Authentication type**, select **Individual Accounts**. +* Select **Create**. + +# [.NET CLI](#tab/net-cli) + +```dotnetcli +dotnet new mvc -au Individual -o WebApplication1 +``` + +The `-o|--output` option creates a folder for the app and sets the app name/namespace. + +The preceding command creates an MVC app using SQLite. To create the web app with LocalDB, run the following command: + +```dotnetcli +dotnet new mvc -au Individual -uld -o WebApplication1 +``` + +--- + +The generated project provides [ASP.NET Core Identity](xref:security/authentication/identity) as a [Razor class library (RCL)](xref:razor-pages/ui-class). The Identity Razor class library is based on Razor Pages and exposes endpoints with the `Identity` area. For example: + +* `Areas/Identity/Pages/Account/Register` +* `Areas/Identity/Pages/Account/Login` +* `Areas/Identity/Pages/Account/Manage/ChangePassword` -* /Identity/Account/Login -* /Identity/Account/Logout -* /Identity/Account/Manage +Pages are described individually in the documentation for specific use cases and are subject to change each release. To view all of the pages in the RCL, see the [ASP.NET Core reference source (`dotnet/aspnetcore` GitHub repository, `Identity/UI/src/Areas/Identity/Pages` folder)](https://github.com/dotnet/aspnetcore/tree/main/src/Identity/UI/src/Areas/Identity/Pages). You can *scaffold* individual pages or all of the pages into the app. For more information, see . ### Apply migrations @@ -243,10 +328,11 @@ To prevent publishing static Identity assets (stylesheets and JavaScript files f ## Next Steps +* * [ASP.NET Core Identity source code](https://github.com/dotnet/aspnetcore/tree/main/src/Identity) * [How to work with Roles in ASP.NET Core Identity](https://www.yogihosting.com/aspnet-core-identity-roles/) -* See [this GitHub issue](https://github.com/dotnet/AspNetCore.Docs/issues/5131) for information on configuring Identity using SQLite. +* For information on configuring Identity using SQLite, see [How to config Identity for SQLite (`dotnet/AspNetCore.Docs` #5131)](https://github.com/dotnet/AspNetCore.Docs/issues/5131). * [Configure Identity](xref:security/authentication/identity-configuration) * * From 4ebaeea38ce3d34eab8ec5e9748ef17e7525ed0f Mon Sep 17 00:00:00 2001 From: Luke Latham <1622880+guardrex@users.noreply.github.com> Date: Thu, 12 Jun 2025 11:38:17 -0400 Subject: [PATCH 3/4] Surface controller attribute requirement (#35619) --- .../fundamentals/openapi/include-metadata.md | 14 +++++++++----- .../openapi/includes/include-metadata9.md | 12 +++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/aspnetcore/fundamentals/openapi/include-metadata.md b/aspnetcore/fundamentals/openapi/include-metadata.md index c06b4cdd4d81..5c44632066ad 100644 --- a/aspnetcore/fundamentals/openapi/include-metadata.md +++ b/aspnetcore/fundamentals/openapi/include-metadata.md @@ -1,7 +1,7 @@ --- title: Include OpenAPI metadata in an ASP.NET Core app author: captainsafia -description: Learn how to add OpenAPI metadata in an ASP.NET Core app +description: Learn how to add OpenAPI metadata in an ASP.NET Core app. ms.author: safia monikerRange: '>= aspnetcore-9.0' ms.custom: mvc @@ -10,15 +10,19 @@ uid: fundamentals/openapi/include-metadata --- # Include OpenAPI metadata in an ASP.NET Core app +This article explains how to add OpenAPI metadata in an ASP.NET Core app. + ## Include OpenAPI metadata for endpoints :::moniker range=">= aspnetcore-10.0" ASP.NET collects metadata from the web app's endpoints and uses it to generate an OpenAPI document. -In controller-based apps, metadata is collected from attributes like [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute), [`[HttpPost]`](xref:Microsoft.AspNetCore.Mvc.HttpPostAttribute), -and [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute). -In minimal APIs, metadata can be collected from attributes, but may also be set by using extension methods -and other strategies, such as returning from route handlers. + +In controller-based apps, metadata is collected from attributes such as [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute), [`[HttpPost]`](xref:Microsoft.AspNetCore.Mvc.HttpPostAttribute), +and [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) when the controller has the [`[ApiController]` attribute](xref:Microsoft.AspNetCore.Mvc.ApiControllerAttribute). + +In minimal APIs, metadata can be collected from attributes but may also be set by using extension methods and other strategies, such as returning from route handlers. + The following table provides an overview of the metadata collected and the strategies for setting it. | Metadata | Attribute | Extension method | Other strategies | diff --git a/aspnetcore/fundamentals/openapi/includes/include-metadata9.md b/aspnetcore/fundamentals/openapi/includes/include-metadata9.md index fce2ae6cdc34..5e1232dd6287 100644 --- a/aspnetcore/fundamentals/openapi/includes/include-metadata9.md +++ b/aspnetcore/fundamentals/openapi/includes/include-metadata9.md @@ -1,10 +1,12 @@ :::moniker range="= aspnetcore-9.0" ASP.NET collects metadata from the web app's endpoints and uses it to generate an OpenAPI document. -In controller-based apps, metadata is collected from attributes like [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute), [`[HttpPost]`](xref:Microsoft.AspNetCore.Mvc.HttpPostAttribute), -and [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute). -In minimal APIs, metadata can be collected from attributes, but may also be set by using extension methods -and other strategies, such as returning from route handlers. + +In controller-based apps, metadata is collected from attributes such as [`[EndpointDescription]`](xref:Microsoft.AspNetCore.Http.EndpointDescriptionAttribute), [`[HttpPost]`](xref:Microsoft.AspNetCore.Mvc.HttpPostAttribute), +and [`[Produces]`](xref:Microsoft.AspNetCore.Mvc.ProducesAttribute) when the controller has the [`[ApiController]` attribute](xref:Microsoft.AspNetCore.Mvc.ApiControllerAttribute). + +In minimal APIs, metadata can be collected from attributes but may also be set by using extension methods and other strategies, such as returning from route handlers. + The following table provides an overview of the metadata collected and the strategies for setting it. | Metadata | Attribute | Extension method | Other strategies | @@ -582,4 +584,4 @@ A schema transformer can be used to override any default metadata or add additio * * [OpenAPI specification](https://spec.openapis.org/oas/v3.0.3) -:::moniker-end \ No newline at end of file +:::moniker-end From bbf2327c860de97e86a9a1c752063d7adce7bcc5 Mon Sep 17 00:00:00 2001 From: Tom Dykstra Date: Thu, 12 Jun 2025 13:27:26 -0700 Subject: [PATCH 4/4] Customizable security descriptors for HTTP.sys (#35616) --- aspnetcore/fundamentals/servers/httpsys.md | 22 +- .../servers/httpsys/includes/httpsys8-9.md | 324 ++++++++++++++++++ .../10.x/HttpSysConfig/Program.cs | 33 ++ 3 files changed, 375 insertions(+), 4 deletions(-) create mode 100644 aspnetcore/fundamentals/servers/httpsys/includes/httpsys8-9.md create mode 100644 aspnetcore/fundamentals/servers/httpsys/samples_snapshot/10.x/HttpSysConfig/Program.cs diff --git a/aspnetcore/fundamentals/servers/httpsys.md b/aspnetcore/fundamentals/servers/httpsys.md index 9c9825950233..cb7a5fa93f07 100644 --- a/aspnetcore/fundamentals/servers/httpsys.md +++ b/aspnetcore/fundamentals/servers/httpsys.md @@ -5,7 +5,7 @@ description: Learn about HTTP.sys, a web server for ASP.NET Core on Windows. Bui monikerRange: '>= aspnetcore-2.1' ms.author: tdykstra ms.custom: mvc -ms.date: 10/30/2023 +ms.date: 06/12/2025 uid: fundamentals/servers/httpsys --- # HTTP.sys web server implementation in ASP.NET Core @@ -14,7 +14,7 @@ uid: fundamentals/servers/httpsys By [Tom Dykstra](https://github.com/tdykstra) and [Chris Ross](https://github.com/Tratcher) -:::moniker range=">= aspnetcore-8.0" +:::moniker range=">= aspnetcore-10.0" [HTTP.sys](/iis/get-started/introduction-to-iis/introduction-to-iis-architecture#hypertext-transfer-protocol-stack-httpsys) is a [web server for ASP.NET Core](xref:fundamentals/servers/index) that only runs on Windows. HTTP.sys is an alternative to [Kestrel](xref:fundamentals/servers/kestrel) server and offers some features that Kestrel doesn't provide. @@ -27,9 +27,11 @@ HTTP.sys supports the following features: * Port sharing * HTTPS with SNI * HTTP/2 over TLS (Windows 10 or later) +* HTTP/3 over TLS (Windows 11 or later) * Direct file transmission * Response caching * WebSockets (Windows 8 or later) +* Customizable security descriptors Supported Windows versions: @@ -60,7 +62,7 @@ HTTP.sys is mature technology that protects against many types of attacks and pr * [Application-Layer Protocol Negotiation (ALPN)](https://tools.ietf.org/html/rfc7301#section-3) connection * TLS 1.2 or later connection -If an HTTP/2 connection is established, [HttpRequest.Protocol](xref:Microsoft.AspNetCore.Http.HttpRequest.Protocol*) reports `HTTP/2`. +If an HTTP/2 connection is established, [HttpRequest.Protocol](xref:Microsoft.AspNetCore.Http.HttpRequest.Protocol%2A) reports `HTTP/2`. HTTP/2 is enabled by default. If an HTTP/2 connection isn't established, the connection falls back to HTTP/1.1. In a future release of Windows, HTTP/2 configuration flags will be available, including the ability to disable HTTP/2 with HTTP.sys. @@ -95,7 +97,6 @@ HTTP.sys delegates to kernel mode authentication with the Kerberos authenticatio ### Support for kernel-mode response buffering In some scenarios, high volumes of small writes with high latency can cause significant performance impact to `HTTP.sys`. This impact is due to the lack of a buffer in the `HTTP.sys` implementation. To improve performance in these scenarios, support for response buffering is included in `HTTP.sys`. Enable buffering by setting [HttpSysOptions.EnableKernelResponseBuffering](https://github.com/dotnet/aspnetcore/blob/main/src/Servers/HttpSys/src/HttpSysOptions.cs#L120) to `true`. - Response buffering should be enabled by an app that does synchronous I/O, or asynchronous I/O with no more than one outstanding write at a time. In these scenarios, response buffering can significantly improve throughput over high-latency connections. Apps that use asynchronous I/O and that may have more than one write outstanding at a time should **_not_** use this flag. Enabling this flag can result in higher CPU and memory usage by HTTP.Sys. @@ -112,6 +113,18 @@ Additional HTTP.sys configuration is handled through [registry settings](https:/ For more information about HTTP.sys options, see . +### Customize security descriptors + +A *request queue* in HTTP.sys is a kernel-level structure that temporarily stores incoming HTTP requests until your application is ready to process them. Manage access to the request queue by using the [RequestQueueSecurityDescriptor](https://source.dot.net/#Microsoft.AspNetCore.Server.HttpSys/HttpSysOptions.cs,a556950881fd2d87) property on . Set it to a instance when configuring your HTTP.sys server. + +By customizing the security descriptor, you can allow or deny specific users or groups access to the request queue. This is useful in scenarios where you want to restrict or delegate HTTP.sys request handling at the operating system level. + +For example, the following code allows all authenticated users but denies guests: + +[!code-csharp[](~/fundamentals/servers/httpsys/samples_snapshot/10.x/HttpSysConfig/Program.cs)] + +The `RequestQueueSecurityDescriptor` property applies only when creating a new request queue. The property doesn't affect existing request queues. + **MaxRequestBodySize** @@ -338,3 +351,4 @@ For information about how to get traces from HTTP.sys, see [HTTP.sys Manageabili :::moniker-end [!INCLUDE [httpsys5-7](~/fundamentals/servers/httpsys/includes/httpsys5-7.md)] +[!INCLUDE [httpsys8-9](~/fundamentals/servers/httpsys/includes/httpsys8-9.md)] diff --git a/aspnetcore/fundamentals/servers/httpsys/includes/httpsys8-9.md b/aspnetcore/fundamentals/servers/httpsys/includes/httpsys8-9.md new file mode 100644 index 000000000000..ecb00d833bfd --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/includes/httpsys8-9.md @@ -0,0 +1,324 @@ + +:::moniker range=">= aspnetcore-8.0 <= aspnetcore-9.0" + +[HTTP.sys](/iis/get-started/introduction-to-iis/introduction-to-iis-architecture#hypertext-transfer-protocol-stack-httpsys) is a [web server for ASP.NET Core](xref:fundamentals/servers/index) that only runs on Windows. HTTP.sys is an alternative to [Kestrel](xref:fundamentals/servers/kestrel) server and offers some features that Kestrel doesn't provide. + +> [!IMPORTANT] +> HTTP.sys isn't compatible with the [ASP.NET Core Module](xref:host-and-deploy/aspnet-core-module) and can't be used with IIS or IIS Express. + +HTTP.sys supports the following features: + +* [Windows Authentication](xref:security/authentication/windowsauth) +* Port sharing +* HTTPS with SNI +* HTTP/2 over TLS (Windows 10 or later) +* HTTP/3 over TLS (Windows 11 or later) +* Direct file transmission +* Response caching +* WebSockets (Windows 8 or later) +* Customizable security descriptors + +Supported Windows versions: + +* Windows 7 or later +* Windows Server 2008 R2 or later + +[View or download sample code](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/fundamentals/servers/httpsys/samples) ([how to download](xref:index#how-to-download-a-sample)) + +## When to use HTTP.sys + +HTTP.sys is useful for deployments where: + +* There's a need to expose the server directly to the Internet without using IIS. + + ![HTTP.sys communicates directly with the Internet](~/fundamentals/servers/httpsys/_static/httpsys-to-internet.png) + +* An internal deployment requires a feature not available in Kestrel. For more information, see [Kestrel vs. HTTP.sys](xref:fundamentals/servers/index#kestrel-vs-httpsys) + + ![HTTP.sys communicates directly with the internal network](~/fundamentals/servers/httpsys/_static/httpsys-to-internal.png) + +HTTP.sys is mature technology that protects against many types of attacks and provides the robustness, security, and scalability of a full-featured web server. IIS itself runs as an HTTP listener on top of HTTP.sys. + +## HTTP/2 support + +[HTTP/2](https://httpwg.org/specs/rfc7540.html) is enabled for ASP.NET Core apps when the following base requirements are met: + +* Windows Server 2016/Windows 10 or later +* [Application-Layer Protocol Negotiation (ALPN)](https://tools.ietf.org/html/rfc7301#section-3) connection +* TLS 1.2 or later connection + +If an HTTP/2 connection is established, [HttpRequest.Protocol](xref:Microsoft.AspNetCore.Http.HttpRequest.Protocol%2A) reports `HTTP/2`. + +HTTP/2 is enabled by default. If an HTTP/2 connection isn't established, the connection falls back to HTTP/1.1. In a future release of Windows, HTTP/2 configuration flags will be available, including the ability to disable HTTP/2 with HTTP.sys. + +## HTTP/3 support + +[HTTP/3](https://datatracker.ietf.org/doc/rfc9114/) is enabled for ASP.NET Core apps when the following base requirements are met: + +* Windows Server 2022/Windows 11 or later +* An `https` url binding is used. +* The [EnableHttp3 registry key](https://techcommunity.microsoft.com/t5/networking-blog/enabling-http-3-support-on-windows-server-2022/ba-p/2676880) is set. + +The preceding Windows 11 Build versions may require the use of a [Windows Insider](https://www.microsoft.com/en-us/windowsinsider/) build. + +HTTP/3 is discovered as an upgrade from HTTP/1.1 or HTTP/2 via the `alt-svc` header. That means the first request will normally use HTTP/1.1 or HTTP/2 before switching to HTTP/3. Http.Sys doesn't automatically add the `alt-svc` header, it must be added by the application. The following code is a middleware example that adds the `alt-svc` response header. + +```csharp +app.Use((context, next) => +{ + context.Response.Headers.AltSvc = "h3=\":443\""; + return next(context); +}); +``` + +Place the preceding code early in the request pipeline. + +Http.Sys also supports sending an AltSvc HTTP/2 protocol message rather than a response header to notify the client that HTTP/3 is available. See the [EnableAltSvc registry key](https://techcommunity.microsoft.com/t5/networking-blog/enabling-http-3-support-on-windows-server-2022/ba-p/2676880). This requires netsh sslcert bindings that use host names rather than IP addresses. + +## Kernel mode authentication with Kerberos + +HTTP.sys delegates to kernel mode authentication with the Kerberos authentication protocol. User mode authentication isn't supported with Kerberos and HTTP.sys. The machine account must be used to decrypt the Kerberos token/ticket that's obtained from Active Directory and forwarded by the client to the server to authenticate the user. Register the Service Principal Name (SPN) for the host, not the user of the app. + +### Support for kernel-mode response buffering + +In some scenarios, high volumes of small writes with high latency can cause significant performance impact to `HTTP.sys`. This impact is due to the lack of a buffer in the `HTTP.sys` implementation. To improve performance in these scenarios, support for response buffering is included in `HTTP.sys`. Enable buffering by setting [HttpSysOptions.EnableKernelResponseBuffering](https://github.com/dotnet/aspnetcore/blob/main/src/Servers/HttpSys/src/HttpSysOptions.cs#L120) to `true`. +Response buffering should be enabled by an app that does synchronous I/O, or asynchronous I/O with no more than one outstanding write at a time. In these scenarios, response buffering can significantly improve throughput over high-latency connections. + +Apps that use asynchronous I/O and that may have more than one write outstanding at a time should **_not_** use this flag. Enabling this flag can result in higher CPU and memory usage by HTTP.Sys. + +## How to use HTTP.sys + +### Configure the ASP.NET Core app to use HTTP.sys + +Call the extension method when building the host, specifying any required . The following example sets options to their default values: + +:::code language="csharp" source="~/fundamentals/servers/httpsys/samples/8.x/SampleApp/Program.cs" id="snippet_1" highlight="8-16"::: + +Additional HTTP.sys configuration is handled through [registry settings](https://support.microsoft.com/help/820129/http-sys-registry-settings-for-windows). + +For more information about HTTP.sys options, see . + + + +**MaxRequestBodySize** + +The maximum allowed size of any request body in bytes. When set to `null`, the maximum request body size is unlimited. This limit has no effect on upgraded connections, which are always unlimited. + +The recommended method to override the limit in an ASP.NET Core MVC app for a single `IActionResult` is to use the attribute on an action method: + +```csharp +[RequestSizeLimit(100000000)] +public IActionResult MyActionMethod() +``` + +An exception is thrown if the app attempts to configure the limit on a request after the app has started reading the request. An `IsReadOnly` property can be used to indicate if the `MaxRequestBodySize` property is in a read-only state, meaning it's too late to configure the limit. + +If the app should override per-request, use the : + +:::code language="csharp" source="~/fundamentals/servers/httpsys/samples/8.x/SampleApp/Program.cs" id="snippet_12" highlight="3-4"::: + +If using Visual Studio, make sure the app isn't configured to run IIS or IIS Express. + +In Visual Studio, the default launch profile is for IIS Express. To run the project as a console app, manually change the selected profile, as shown in the following screenshot: + +:::image type="content" source="~/fundamentals/servers/httpsys/_static/vs-choose-profile.png" alt-text="Select console app profile"::: + +### Configure Windows Server + +1. Determine the ports to open for the app and use [Windows Firewall](/windows/security/threat-protection/windows-firewall/create-an-inbound-port-rule) or the [New-NetFirewallRule](/powershell/module/netsecurity/new-netfirewallrule) PowerShell cmdlet to open firewall ports to allow traffic to reach HTTP.sys. In the following commands and app configuration, port 443 is used. + +1. When deploying to an Azure VM, open the ports in the [Network Security Group](/azure/virtual-machines/windows/nsg-quickstart-portal). In the following commands and app configuration, port 443 is used. + +1. Obtain and install X.509 certificates, if required. + + On Windows, create self-signed certificates using the [New-SelfSignedCertificate PowerShell cmdlet](/powershell/module/pki/new-selfsignedcertificate). For an unsupported example, see [UpdateIISExpressSSLForChrome.ps1](https://github.com/dotnet/AspNetCore.Docs/tree/main/aspnetcore/includes/make-x509-cert/UpdateIISExpressSSLForChrome.ps1). + + Install either self-signed or CA-signed certificates in the server's **Local Machine** > **Personal** store. + +1. If the app is a [framework-dependent deployment](/dotnet/core/deploying/#framework-dependent-deployments-fdd), install .NET Core, .NET Framework, or both (if the app is a .NET Core app targeting the .NET Framework). + + * **.NET Core**: If the app requires .NET Core, obtain and run the **.NET Core Runtime** installer from [.NET Core Downloads](https://dotnet.microsoft.com/download). Don't install the full SDK on the server. + * **.NET Framework**: If the app requires .NET Framework, see the [.NET Framework installation guide](/dotnet/framework/install/). Install the required .NET Framework. The installer for the latest .NET Framework is available from the [.NET Core Downloads](https://dotnet.microsoft.com/download) page. + + If the app is a [self-contained deployment](/dotnet/core/deploying/#self-contained-deployments-scd), the app includes the runtime in its deployment. No framework installation is required on the server. + +1. Configure URLs and ports in the app. + + By default, ASP.NET Core binds to `http://localhost:5000`. To configure URL prefixes and ports, options include: + + * + * `urls` command-line argument + * `ASPNETCORE_URLS` environment variable + * + + The following code example shows how to use with the server's local IP address `10.0.0.4` on port 443: + + :::code language="csharp" source="~/fundamentals/servers/httpsys/samples/8.x/SampleApp/Program.cs" id="snippet_11" highlight="5"::: + + An advantage of `UrlPrefixes` is that an error message is generated immediately for improperly formatted prefixes. + + The settings in `UrlPrefixes` override `UseUrls`/`urls`/`ASPNETCORE_URLS` settings. Therefore, an advantage of `UseUrls`, `urls`, and the `ASPNETCORE_URLS` environment variable is that it's easier to switch between Kestrel and HTTP.sys. + + HTTP.sys recognizes two types of wild cards in URL prefixes: + + * `*` is a *weak binding*, also known as a *fallback binding*. If the URL prefix is `http://*:5000`, and something else is bound to port 5000, this binding won't be used. + * `+` is a *strong binding*. If the URL prefix is `http://+:5000`, this binding will be used before other port 5000 bindings. + + For more information, see [UrlPrefix Strings](/windows/win32/http/urlprefix-strings). + + > [!WARNING] + > Top-level wildcard bindings (`http://*:80/` and `http://+:80`) should **not** be used. Top-level wildcard bindings create app security vulnerabilities. This applies to both strong and weak wildcards. Use explicit host names or IP addresses rather than wildcards. Subdomain wildcard binding (for example, `*.mysub.com`) isn't a security risk if you control the entire parent domain (as opposed to `*.com`, which is vulnerable). For more information, see [RFC 9110: Section 7.2: Host and :authority](https://www.rfc-editor.org/rfc/rfc9110#field.host). + + [!INCLUDE [http-ports](~/includes/http-ports.md)] + + These configuration keys are equivalent to top-level wildcard bindings. They're convenient for development and container scenarios, but avoid wildcards when running on a machine that may also host other services. + +1. Preregister URL prefixes on the server. + + The built-in tool for configuring HTTP.sys is *netsh.exe*. *netsh.exe* is used to reserve URL prefixes and assign X.509 certificates. The tool requires administrator privileges. + + Use the *netsh.exe* tool to register URLs for the app: + + ```console + netsh http add urlacl url= user= + ``` + + * ``: The fully qualified Uniform Resource Locator (URL). Don't use a wildcard binding. Use a valid hostname or local IP address. *The URL must include a trailing slash.* + * ``: Specifies the user or user-group name. + + In the following example, the local IP address of the server is `10.0.0.4`: + + ```console + netsh http add urlacl url=https://10.0.0.4:443/ user=Users + ``` + + When a URL is registered, the tool responds with `URL reservation successfully added`. + + To delete a registered URL, use the `delete urlacl` command: + + ```console + netsh http delete urlacl url= + ``` + +1. Register X.509 certificates on the server. + + Use the *netsh.exe* tool to register certificates for the app: + + ```console + netsh http add sslcert ipport=: certhash= appid="{}" + ``` + + * ``: Specifies the local IP address for the binding. Don't use a wildcard binding. Use a valid IP address. + * ``: Specifies the port for the binding. + * ``: The X.509 certificate thumbprint. + * ``: A developer-generated GUID to represent the app for informational purposes. + + For reference purposes, store the GUID in the app as a package tag: + + * In Visual Studio: + * Open the app's project properties by right-clicking on the app in **Solution Explorer** and selecting **Properties**. + * Select the **Package** tab. + * Enter the GUID that you created in the **Tags** field. + * When not using Visual Studio: + * Open the app's project file. + * Add a `` property to a new or existing `` with the GUID that you created: + + ```xml + + 00001111-aaaa-2222-bbbb-3333cccc4444 + + ``` + + In the following example: + + * The local IP address of the server is `10.0.0.4`. + * An online random GUID generator provides the `appid` value. + + ```console + netsh http add sslcert + ipport=10.0.0.4:443 + certhash=b66ee04419d4ee37464ab8785ff02449980eae10 + appid="{00001111-aaaa-2222-bbbb-3333cccc4444}" + ``` + + When a certificate is registered, the tool responds with `SSL Certificate successfully added`. + + To delete a certificate registration, use the `delete sslcert` command: + + ```console + netsh http delete sslcert ipport=: + ``` + + Reference documentation for *netsh.exe*: + + * [Netsh Commands for Hypertext Transfer Protocol (HTTP)](/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/cc725882(v=ws.10)) + * [UrlPrefix Strings](/windows/win32/http/urlprefix-strings) + +1. Run the app. + + Administrator privileges aren't required to run the app when binding to localhost using HTTP (not HTTPS) with a port number greater than 1024. For other configurations (for example, using a local IP address or binding to port 443), run the app with administrator privileges. + + The app responds at the server's public IP address. In this example, the server is reached from the Internet at its public IP address of `104.214.79.47`. + + A development certificate is used in this example. The page loads securely after bypassing the browser's untrusted certificate warning. + + ![Browser window showing the app's Index page loaded](~/fundamentals/servers/httpsys/_static/browser.png) + +## Proxy server and load balancer scenarios + +For apps hosted by HTTP.sys that interact with requests from the Internet or a corporate network, additional configuration might be required when hosting behind proxy servers and load balancers. For more information, see [Configure ASP.NET Core to work with proxy servers and load balancers](xref:host-and-deploy/proxy-load-balancer). + + + +## Get detailed timing information with IHttpSysRequestTimingFeature + +[IHttpSysRequestTimingFeature](/dotnet/api/microsoft.aspnetcore.server.httpsys.ihttpsysrequesttimingfeature) provides detailed timing information for requests: + +* Timestamps are obtained using [QueryPerformanceCounter](/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter). +* The timestamp frequency can be obtained via [QueryPerformanceFrequency](/windows/win32/api/profileapi/nf-profileapi-queryperformancefrequency). +* The index of the timing can be cast to [HttpSysRequestTimingType](/dotnet/api/microsoft.aspnetcore.server.httpsys.httpsysrequesttimingtype) to know what the timing represents. +* The value may be 0 if the timing isn't available for the current request. +* Requires Windows 10 version 2004, Windows Server 2022, or later. + +:::code language="csharp" source="~/fundamentals/request-features/samples/8.x/IHttpSysRequestTimingFeature/Program.cs" id="snippet_WithTimestamps"::: + +[IHttpSysRequestTimingFeature.TryGetTimestamp](xref:Microsoft.AspNetCore.Server.HttpSys.IHttpSysRequestTimingFeature.TryGetTimestamp%2A) retrieves the timestamp for the provided timing type: + +:::code language="csharp" source="~/fundamentals/request-features/samples/8.x/IHttpSysRequestTimingFeature/Program.cs" id="snippet_WithTryGetTimestamp"::: + +[IHttpSysRequestTimingFeature.TryGetElapsedTime](/dotnet/api/microsoft.aspnetcore.server.httpsys.ihttpsysrequesttimingfeature.trygetelapsedtime yields the elapsed time between two specified timings: + +:::code language="csharp" source="~/fundamentals/request-features/samples/8.x/IHttpSysRequestTimingFeature/Program.cs" id="snippet_WithTryGetElapsedTime"::: + +## Advanced HTTP/2 features to support gRPC + +Additional HTTP/2 features in HTTP.sys support gRPC, including support for response trailers and sending reset frames. + +Requirements to run gRPC with HTTP.sys: + +* Windows 11 Build 22000 or later, Windows Server 2022 Build 20348 or later. +* TLS 1.2 or later connection. + +### Trailers + +[!INCLUDE[](~/includes/trailers.md)] + +### Reset + +[!INCLUDE[](~/includes/reset.md)] + +## Tracing + +For information about how to get traces from HTTP.sys, see [HTTP.sys Manageability Scenarios](/windows/win32/http/http-sys-manageability-scenarios). + +## Additional resources + +* [Enable Windows Authentication with HTTP.sys](xref:security/authentication/windowsauth#httpsys) +* [HTTP Server API](/windows/win32/http/http-api-start-page) +* [aspnet/HttpSysServer GitHub repository (source code)](https://github.com/aspnet/HttpSysServer/) +* [The host](xref:fundamentals/index#host) +* + +:::moniker-end diff --git a/aspnetcore/fundamentals/servers/httpsys/samples_snapshot/10.x/HttpSysConfig/Program.cs b/aspnetcore/fundamentals/servers/httpsys/samples_snapshot/10.x/HttpSysConfig/Program.cs new file mode 100644 index 000000000000..28cedb07ca94 --- /dev/null +++ b/aspnetcore/fundamentals/servers/httpsys/samples_snapshot/10.x/HttpSysConfig/Program.cs @@ -0,0 +1,33 @@ +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.BuiltinUsersSid, 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; +});