Skip to content

Commit 45cbae6

Browse files
Update System.Web adapters docs for 2.2.0 (#36481)
* Update System.Web adapters docs for 2.2.0 * add to toc * spelling * clean up doc * remove note * explains the value of swa machinekey * reorganize for clairy * Apply suggestions from code review Co-authored-by: Wade Pickett <wpickett@microsoft.com> --------- Co-authored-by: Wade Pickett <wpickett@microsoft.com>
1 parent 5692e25 commit 45cbae6

6 files changed

Lines changed: 156 additions & 79 deletions

File tree

aspnetcore/migration/fx-to-core/areas/authentication.md

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
title: ASP.NET Framework to Core Authentication Migration
3+
ai-usage: ai-assisted
4+
author: twsouthwick
35
description: ASP.NET Framework to Core Authentication Migration
4-
author: wadepickett
5-
ms.author: wpickett
66
monikerRange: '>= aspnetcore-6.0'
7-
ms.date: 09/24/2025
7+
ms.author: tasou
8+
ms.date: 12/10/2025
89
ms.topic: article
910
uid: migration/fx-to-core/areas/authentication
1011
zone_pivot_groups: migration-remote-app-setup
@@ -216,6 +217,15 @@ var coreApp = builder.AddProject<Projects.AuthRemoteIdentityCore>("core")
216217
Once this is done, it will be automatically hooked up in both the framework and core applications.
217218
:::zone-end
218219

220+
#### Remote authentication with YARP fallback
221+
222+
When using remote authentication with YARP-based fallback to the ASP.NET Framework app, make sure that fallback requests don't invoke remote authentication. If remote authentication runs during fallback, the app makes unnecessary extra calls back to the Framework app and can lead to confusing behavior.
223+
224+
To avoid running remote authentication for fallback requests, use one of these approaches:
225+
226+
* Use routing short-circuit metadata on the YARP fallback route so that the route bypasses the rest of the middleware pipeline. For example, call `ShortCircuit` on the fallback endpoint as shown in the remote app setup guidance and in [Short-circuit middleware after routing](xref:fundamentals/routing#short-circuit-middleware-after-routing).
227+
* Don't use remote authentication as the default authentication scheme. Instead, configure remote authentication only for the endpoints that need it. For example, pass `false` to `AddAuthenticationClient` and specify the remote authentication scheme explicitly on those endpoints.
228+
219229
#### Using Remote Authentication with Specific Endpoints
220230

221231
When you set the default scheme to `false`, you can specify remote authentication for specific controllers or actions:
@@ -340,7 +350,7 @@ Note that because signing in typically depends on a specific database, not all a
340350
* Both apps are able to see the users' identity and claims.
341351
* Both apps are able to sign the user out.
342352

343-
Details on how to configure sharing auth cookies between ASP.NET and ASP.NET Core apps are available in [cookie sharing documentation](xref:security/cookie-sharing). For more information about cookie authentication in ASP.NET Core, see <xref:security/authentication/cookie>.
353+
Details on how to configure sharing auth cookies between ASP.NET and ASP.NET Core apps are available in [cookie sharing documentation](xref:security/cookie-sharing). For more information about cookie authentication in ASP.NET Core, see <xref:security/authentication/cookie>. For guidance on configuring `<machineKey>` and data protection when sharing protected values between Framework and Core apps, see <xref:migration/fx-to-core/areas/machine-key>.
344354

345355
The following samples in the [System.Web adapters](https://github.com/dotnet/systemweb-adapters) GitHub repo demonstrates remote app authentication with shared cookie configuration enabling both apps to sign users in and out:
346356

aspnetcore/migration/fx-to-core/areas/hosting.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ ai-usage: ai-assisted
55
author: twsouthwick
66
ms.author: tasou
77
monikerRange: '>= aspnetcore-6.0'
8-
ms.date: 11/10/2025
8+
ms.date: 12/10/2025
99
ms.topic: article
1010
uid: migration/fx-to-core/areas/hosting
1111
---
@@ -61,9 +61,6 @@ The `HttpApplicationHost.RegisterHost` method configures a generic host that run
6161

6262
## Dependency injection
6363

64-
> [!NOTE]
65-
> This currently is in a preview version of the adapters. You must be using 2.2.0-preview1.25554.5 or greater to use this feature.
66-
6764
The `AddSystemWebDependencyInjection` method enables dependency injection throughout your ASP.NET Framework application. Services registered with the generic host's service collection become available to controllers, handlers, and other components.
6865

6966
This extension method is an internal method that will be source generated depending on what you have referenced. The following frameworks are supported:
@@ -72,6 +69,9 @@ This extension method is an internal method that will be source generated depend
7269
- ASP.NET MVC using <xref:System.Web.Mvc.DependencyResolver>
7370
- ASP.NET WebApi using [DependencyResolver](/previous-versions/aspnet/hh969140(v=vs.108))
7471

72+
> [!NOTE]
73+
> The `builder.AddSystemWebDependencyInjection()` extension method is generated by a C# source generator and is only available in C# projects. For VB.NET apps, create an intermediate C# class library that references the ASP.NET MVC/Web API and SystemWebAdapters packages. Configure dependency injection in that library and expose a public method that your VB.NET project can call.
74+
7575
### Registering services
7676

7777
Register services with the dependency injection container by accessing the `Services` property on the host builder:

aspnetcore/migration/fx-to-core/areas/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
---
22
title: Complex migration scenarios - Deep dive areas
3+
ai-usage: ai-assisted
34
description: Detailed guidance for complex ASP.NET Framework to ASP.NET Core migration scenarios
45
author: twsouthwick
56
ms.author: tasou
6-
ms.date: 11/10/2025
7+
ms.date: 12/10/2025
78
uid: migration/fx-to-core/areas
89
---
910
# Technology specific guidance
@@ -14,6 +15,7 @@ uid: migration/fx-to-core/areas
1415
* [HttpContext](http-context.md)
1516
* [HTTP Handlers](http-handlers.md)
1617
* [HTTP Modules](http-modules.md)
18+
* [Machine Key](machine-key.md)
1719
* [Membership](membership.md)
1820
* [Miscellaneous](misc.md)
1921
* [OWIN](owin.md)
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
---
2+
title: ASP.NET machineKey to ASP.NET Core migration
3+
ai-usage: ai-assisted
4+
author: twsouthwick
5+
description: Migrate ASP.NET machineKey-based cryptography to ASP.NET Core data protection in incremental and full migrations.
6+
monikerRange: '>= aspnetcore-6.0'
7+
ms.author: tasou
8+
ms.date: 12/10/2025
9+
ms.topic: article
10+
uid: migration/fx-to-core/areas/machine-key
11+
---
12+
13+
# Migrate ASP.NET machineKey by using System.Web adapters
14+
15+
[!INCLUDE[](~/migration/fx-to-core/includes/uses-systemweb-adapters.md)]
16+
17+
In the ASP.NET Framework app, configure `<machineKey>` and the System.Web adapters host so that both apps can share a compatible data protection configuration. For full background on replacing `<machineKey>`, see <xref:security/data-protection/compatibility/replacing-machinekey>.
18+
19+
This guidance builds on the `System.Web` adapters hosting model so that data protection services are registered in the host dependency injection (DI) container and made available throughout the ASP.NET Framework app. By integrating with the host DI provided by the adapters, existing ASP.NET Framework components can resolve `IDataProtectionProvider`, `IDataProtector`, and related types.
20+
21+
Both the ASP.NET Framework app and the ASP.NET Core app must use a shared application name and key repository for data protection so that protected payloads can round-trip between apps.
22+
23+
* Call `SetApplicationName` with the same logical application name in both apps (for example, `"my-app"`).
24+
* Configure `PersistKeysToFileSystem` to point to the same key repository location that both apps can read and write.
25+
26+
> [!NOTE]
27+
> The directory used with `PersistKeysToFileSystem` is the backing store for the shared data protection keys. In production, use a durable, shared store (such as a UNC share, Redis, or Azure Blob Storage) and follow the key management guidance in <xref:security/data-protection/configuration/overview> and <xref:security/data-protection/introduction>.
28+
29+
## Configure the ASP.NET Framework app
30+
31+
To implement this configuration in the ASP.NET Framework app, ensure the `Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices` package is installed in the ASP.NET Framework app.
32+
33+
When you install the `Microsoft.AspNetCore.SystemWebAdapters.FrameworkServices` package in the ASP.NET Framework app, it normally configures `<machineKey>` automatically. If `<machineKey>` isn't present or you need to verify the settings, configure `` in *Web.config* to use the compatibility data protector as shown:
34+
35+
```xml
36+
<configuration>
37+
<system.web>
38+
<httpRuntime targetFramework="4.8.1" />
39+
<machineKey
40+
compatibilityMode="Framework45"
41+
dataProtectorType="Microsoft.AspNetCore.DataProtection.SystemWeb.CompatibilityDataProtector,
42+
Microsoft.AspNetCore.DataProtection.SystemWeb" />
43+
</system.web>
44+
</configuration>
45+
```
46+
47+
Next, in `Global.asax.cs`, register the System.Web adapters host and configure data protection using the same application name and key repository that the ASP.NET Core app will use. The following example is adapted from the MachineKey Framework sample:
48+
49+
```csharp
50+
using System.IO;
51+
using System.Web;
52+
using Microsoft.AspNetCore.DataProtection;
53+
using Microsoft.AspNetCore.SystemWebAdapters.Hosting;
54+
using Microsoft.Extensions.DependencyInjection;
55+
using Microsoft.Extensions.Hosting;
56+
57+
namespace DataProtectionDemo
58+
{
59+
public class MvcApplication : HttpApplication
60+
{
61+
protected void Application_Start()
62+
{
63+
HttpApplicationHost.RegisterHost(builder =>
64+
{
65+
builder.AddServiceDefaults();
66+
67+
builder.AddDataProtection()
68+
.SetApplicationName("my-app")
69+
.PersistKeysToFileSystem(new DirectoryInfo(@"\\server\share\myapp-keys\"));
70+
});
71+
}
72+
}
73+
}
74+
```
75+
76+
This configuration:
77+
78+
* Sets a shared application name (`my-app`) that the ASP.NET Core app must also use.
79+
* Configures a shared key repository (for example, a UNC share) that both apps can access.
80+
* Ensures `<machineKey>` operations (forms auth, view state, `MachineKey.Protect`, and related APIs) are routed through ASP.NET Core data protection.
81+
* Runs as part of the ASP.NET Framework host so that existing `<machineKey>`-based features use the same data protection system as ASP.NET Core.
82+
83+
## Configure the ASP.NET Core app
84+
85+
No additional configuration is required for data protection in the ASP.NET Core app. Just configure the same application name and key storage location that the ASP.NET Framework app uses.
86+
87+
```csharp
88+
using Microsoft.AspNetCore.DataProtection;
89+
90+
var builder = WebApplication.CreateBuilder(args);
91+
92+
builder.Services.AddDataProtection()
93+
.SetApplicationName(MachineKeyExampleHandler.AppName)
94+
.PersistKeysToFileSystem(
95+
new DirectoryInfo(Path.Combine(Path.GetTempPath(), "sharedkeys", MachineKeyExampleHandler.AppName)));
96+
97+
var app = builder.Build();
98+
99+
// Configure application
100+
101+
app.Run();
102+
```

aspnetcore/migration/fx-to-core/inc/remote-app-setup.md

Lines changed: 31 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
---
22
title: Remote app setup
3-
description: Remote app setup
3+
ai-usage: ai-assisted
44
author: wadepickett
5-
ms.author: wpickett
5+
description: Remote app setup
66
monikerRange: '>= aspnetcore-6.0'
7-
ms.date: 10/08/2025
7+
ms.author: wpickett
8+
ms.date: 12/10/2025
89
ms.topic: article
910
uid: migration/fx-to-core/inc/remote-app-setup
1011
zone_pivot_groups: migration-remote-app-setup
@@ -157,51 +158,27 @@ To enable proxying from the ASP.NET Core application to the ASP.NET Framework ap
157158
## Setup Aspire orchestration
158159

159160
> [!IMPORTANT]
160-
> This is still in preview and not available on NuGet.org, so you must configure your NuGet config to pull libraries from the .NET Libraries daily feed:
161-
>
162-
> ```xml
163-
> <?xml version="1.0" encoding="utf-8"?>
164-
> <configuration>
165-
> <packageSources>
166-
> <!--To inherit the global NuGet package sources remove the <clear/> line below -->
167-
> <clear />
168-
> <add key="nuget" value="https://api.nuget.org/v3/index.json" />
169-
> <add key=".NET Libraries Daily" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-libraries/nuget/v3/index.json" />
170-
> </packageSources>
171-
> </configuration>
172-
> ```
173-
>
174-
> **NOTE**: This requires v2.0.1-preview1.25351.5 of the System.Web adapters or later.
175-
176-
> [!WARNING]
177-
> **NOTE**: This is a 3rd party component that helps run the application in Aspire. At the current time, ASP.NET Framework applications are not supported directly in Aspire, but this project helps with that. This dependency is intended for build and development, but does not need to be deployed into production.
161+
> This integration is currently in preview and is published as a prerelease package on NuGet.org. When adding the package, enable prerelease packages in your tooling (for example, select `Include prerelease` in Visual Studio's NuGet Package Manager or use the equivalent prerelease option with the .NET CLI).
178162

179163
1. Add Aspire orchestration for the ASP.NET Framework application
180164
1. Add a new ASP.NET Core application to the solution and add it to your Aspire orchestration
181-
1. Update the AppHost to target Windows as IIS integration requires that:
182-
```diff
183-
- <TargetFramework>net9.0</TargetFramework>
184-
+ <TargetFramework>net9.0-windows</TargetFramework>
185-
```
186-
1. Add the following Aspire integrations to your app host:
187-
* `Aspire.Hosting.IncrementalMigration`
188-
* `C3D.Extensions.Aspire.IISExpress`
189-
1. Configure IIS Express to locally host your framework application and configure incremental migration fallback:
165+
1. Add the `Aspire.Hosting.IncrementalMigration` package to your AppHost project.
166+
1. Configure IIS Express to locally host your framework application and configure incremental migration fallback using the incremental migration extensions:
190167

191168
```csharp
192169
var builder = DistributedApplication.CreateBuilder(args);
193-
194-
var frameworkApp = builder.AddIISExpress("iis")
195-
.AddSiteProject<Projects.FrameworkApplication>("framework")
196-
.WithDefaultIISExpressEndpoints()
197-
.WithOtlpExporter()
198-
.WithHttpHealthCheck();
199-
170+
171+
// Add ASP.NET Framework app with IIS Express
172+
var frameworkApp = builder.AddIISExpressProject<Projects.FrameworkApplication>("framework");
173+
174+
// Add ASP.NET Core app with fallback to Framework app
200175
var coreApp = builder.AddProject<Projects.CoreApplication>("core")
201-
.WithHttpHealthCheck()
202-
.WaitFor(frameworkApp)
203-
.WithIncrementalMigrationFallback(frameworkApp, options => options.RemoteSession = RemoteSession.Enabled);
204-
176+
.WithIncrementalMigrationFallback(frameworkApp, options =>
177+
{
178+
options.RemoteSession = RemoteSession.Enabled;
179+
options.RemoteAuthentication = RemoteAuthentication.DefaultScheme;
180+
});
181+
205182
builder.Build().Run();
206183
```
207184
1. Configure the options of the incremental migration fallback for the scenarios you want to support.
@@ -212,48 +189,30 @@ To enable proxying from the ASP.NET Core application to the ASP.NET Framework ap
212189
1. Update the ServiceDefaults project to support .NET Framework. This is based off of the default ServiceDefaults and may differ if you have customized anything.
213190
* Update the target framework to multitarget:
214191
```diff
215-
- <TargetFramework>net9.0</TargetFramework>
216-
+ <TargetFrameworks>net9.0;net48</TargetFrameworks>
192+
- <TargetFramework>net10.0</TargetFramework>
193+
+ <TargetFrameworks>net481;net10.0</TargetFrameworks>
217194
```
218195
* Update the PackageReferences to account for the different frameworks:
219196
```xml
220-
<ItemGroup>
197+
<ItemGroup>
221198
<PackageReference Include="Microsoft.Extensions.Http.Resilience" />
199+
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
222200
<PackageReference Include="OpenTelemetry.Exporter.OpenTelemetryProtocol" />
223201
<PackageReference Include="OpenTelemetry.Extensions.Hosting" />
224202
<PackageReference Include="OpenTelemetry.Instrumentation.Http" />
225203
<PackageReference Include="OpenTelemetry.Instrumentation.Runtime" />
226204
<PackageReference Include="OpenTelemetry.Instrumentation.SqlClient" />
227-
</ItemGroup>
228-
229-
<ItemGroup Condition=" '$(TargetFramework)' == 'net9.0'">
205+
</ItemGroup>
206+
207+
<ItemGroup Condition=" '$(TargetFramework)' == 'net10.0' ">
230208
<FrameworkReference Include="Microsoft.AspNetCore.App" />
231-
232-
<PackageReference Include="Microsoft.Extensions.ServiceDiscovery" />
233209
<PackageReference Include="OpenTelemetry.Instrumentation.AspNetCore" />
234-
</ItemGroup>
235-
236-
<ItemGroup Condition=" '$(TargetFramework)' == 'net48' ">
210+
</ItemGroup>
211+
212+
<ItemGroup Condition=" '$(TargetFramework)' == 'net481' ">
237213
<PackageReference Include="Microsoft.Extensions.Diagnostics.HealthChecks" />
238214
<PackageReference Include="OpenTelemetry.Instrumentation.AspNet" />
239-
</ItemGroup>
240-
```
241-
* In the Extensions.cs file, you'll need to conditionally exclude the ServiceDiscovery APIs as those are currently not supported on .NET Framework:
242-
```diff
243-
+ #if NET
244-
builder.Services.AddServiceDiscovery();
245-
+ #endif
246-
247-
builder.Services.ConfigureHttpClientDefaults(http =>
248-
{
249-
// Turn on resilience by default
250-
http.AddStandardResilienceHandler();
251-
252-
+ #if NET
253-
// Turn on service discovery by default
254-
http.AddServiceDiscovery();
255-
+ #endif
256-
});
215+
</ItemGroup>
257216
```
258217
* To enable telemetry, update the metrics and tracing registrations:
259218

@@ -294,6 +253,8 @@ To enable proxying from the ASP.NET Core application to the ASP.NET Framework ap
294253
+ #endif
295254
```
296255

256+
For a complete, working example of a multi-targeted `ServiceDefaults` configuration that supports both ASP.NET Core and ASP.NET Framework, see the sample `Extensions.cs` file in the System.Web adapters repository: `https://github.com/dotnet/systemweb-adapters/blob/main/samples/ServiceDefaults/Extensions.cs`.
257+
297258
## Configure ASP.NET Framework Application
298259

299260
1. Reference the ServiceDefaults project

aspnetcore/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2177,6 +2177,8 @@ items:
21772177
uid: migration/fx-to-core/areas/http-modules
21782178
- name: HTTP Handlers
21792179
uid: migration/fx-to-core/areas/http-handlers
2180+
- name: Machine Key
2181+
uid: migration/fx-to-core/areas/machine-key
21802182
- name: Session
21812183
uid: migration/fx-to-core/areas/session
21822184
- name: Authentication

0 commit comments

Comments
 (0)