Skip to content

Commit 2187c92

Browse files
authored
Add docs for migrating owin pipelines with system.web adapters (#36323)
* Add docs for migrating owin pipelines with system.web adapters * clean up sample
1 parent e0218fa commit 2187c92

File tree

3 files changed

+372
-0
lines changed

3 files changed

+372
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ uid: migration/fx-to-core/areas
1616
* [HTTP Modules](http-modules.md)
1717
* [Membership](membership.md)
1818
* [Miscellaneous](misc.md)
19+
* [OWIN](owin.md)
1920
* [Session State](session.md)
2021
* [WebAPI](webapi.md)
2122

Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
---
2+
title: OWIN integration in ASP.NET Core
3+
description: How to use OWIN middleware in ASP.NET Core applications during migration from ASP.NET Framework
4+
ai-usage: ai-assisted
5+
author: twsouthwick
6+
ms.author: tasou
7+
monikerRange: '>= aspnetcore-6.0'
8+
ms.date: 11/10/2025
9+
ms.topic: article
10+
uid: migration/fx-to-core/areas/owin
11+
---
12+
13+
# OWIN integration
14+
15+
The `Microsoft.AspNetCore.SystemWebAdapters.Owin` library enables ASP.NET Core applications to use OWIN middleware during migration from ASP.NET Framework. This integration is valuable when migrating applications that rely on OWIN-based middleware, particularly for authentication, authorization, or custom pipeline components.
16+
17+
> [!WARNING]
18+
> When using OWIN integration, you may need to suppress build warnings for .NET Framework package dependencies. Add the following to your project file:
19+
> ```xml
20+
> <PropertyGroup>
21+
> <NoWarn>$(NoWarn);NU1701</NoWarn>
22+
> </PropertyGroup>
23+
> ```
24+
> Running .NET Framework code on .NET Core is supported as long as the APIs used exist and have the same behavior. It is recommended to use this as part of the migration process, but to not stay in this state for too long.
25+
>
26+
> Some packages will need to be manually updated to supported version if used. These include:
27+
> * EntityFramework must be >= 6.5.1 for best support on .NET Core
28+
29+
## Why use OWIN integration
30+
31+
OWIN integration provides several benefits during migration:
32+
33+
* **Preserve existing middleware**: Reuse OWIN middleware from your ASP.NET Framework application without immediate rewrites
34+
* **Gradual migration**: Migrate middleware components incrementally while maintaining application functionality
35+
* **Authentication continuity**: Maintain authentication state and share cookies between ASP.NET Framework and ASP.NET Core applications during migration
36+
* **Familiar patterns**: Continue using OWIN APIs and patterns that your team already understands
37+
38+
## Integration patterns
39+
40+
The library provides three distinct integration patterns, each suited for different migration scenarios:
41+
42+
1. **OWIN pipeline as main pipeline middleware**: Add OWIN middleware directly to the ASP.NET Core middleware pipeline
43+
2. **OWIN pipeline as authentication handler**: Use OWIN middleware as an ASP.NET Core authentication handler
44+
3. **OWIN pipeline in emulated HttpApplication events**: Run OWIN middleware within the emulated `HttpApplication` pipeline
45+
46+
## OWIN pipeline as middleware
47+
48+
This pattern incorporates OWIN middleware into the ASP.NET Core middleware pipeline without using emulated `HttpApplication` events.
49+
50+
### When to use this pattern
51+
52+
Use this approach when:
53+
54+
* You want standard middleware pipeline behavior
55+
* Your application doesn't rely on `HttpApplication` events
56+
* You're gradually migrating OWIN middleware to ASP.NET Core patterns
57+
58+
### Setup
59+
60+
Add OWIN middleware to the main pipeline:
61+
62+
```csharp
63+
var builder = WebApplication.CreateBuilder(args);
64+
65+
var app = builder.Build();
66+
67+
app.UseOwin(owinApp =>
68+
{
69+
owinApp.UseMyOwinMiddleware();
70+
});
71+
72+
app.UseRouting();
73+
app.MapControllers();
74+
75+
app.Run();
76+
```
77+
78+
### Access services
79+
80+
Access services when configuring OWIN middleware:
81+
82+
```csharp
83+
app.UseOwin((owinApp, services) =>
84+
{
85+
var configuration = services.GetRequiredService<IConfiguration>();
86+
owinApp.UseMyOwinMiddleware(configuration);
87+
});
88+
```
89+
90+
## OWIN authentication handler
91+
92+
This pattern uses OWIN middleware as an ASP.NET Core authentication handler, integrating with the `AuthenticationBuilder` API.
93+
94+
### When to use this pattern
95+
96+
Use this approach when:
97+
98+
* Migrating authentication logic from ASP.NET Framework
99+
* Sharing authentication cookies between ASP.NET Framework and ASP.NET Core applications
100+
* Using OWIN authentication middleware such as cookie authentication or OAuth providers
101+
* Working with ASP.NET Framework Identity
102+
103+
### Setup
104+
105+
Register OWIN authentication as an ASP.NET Core authentication handler:
106+
107+
```csharp
108+
var builder = WebApplication.CreateBuilder(args);
109+
110+
builder.Services.AddAuthentication()
111+
.AddOwinAuthentication((owinApp, services) =>
112+
{
113+
owinApp.UseCookieAuthentication(new CookieAuthenticationOptions
114+
{
115+
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
116+
LoginPath = new PathString("/Account/Login")
117+
});
118+
});
119+
120+
var app = builder.Build();
121+
122+
app.UseAuthentication();
123+
app.UseAuthorization();
124+
125+
// Additional middleware or endpoint mapping
126+
127+
app.Run();
128+
```
129+
130+
### Custom authentication scheme
131+
132+
Specify a custom authentication scheme name:
133+
134+
```csharp
135+
builder.Services
136+
.AddAuthentication()
137+
.AddOwinAuthentication("MyOwinScheme", (owinApp, services) =>
138+
{
139+
owinApp.UseMyOwinAuthenticationMiddleware();
140+
});
141+
```
142+
143+
When no scheme name is provided, the authentication handler uses `OwinAuthenticationDefaults.AuthenticationScheme` as the default scheme. The authentication scheme name determines:
144+
145+
* **Default authentication**: If set as the default scheme, it automatically authenticates requests without requiring an `[Authorize]` attribute
146+
* **Challenge behavior**: Controls which handler responds to authentication challenges (such as redirecting to a login page)
147+
* **Authentication selection**: Allows you to explicitly authenticate against a specific scheme using `HttpContext.AuthenticateAsync("scheme-name")`
148+
149+
For applications with multiple authentication schemes, you can configure the default authentication and challenge schemes:
150+
151+
```csharp
152+
builder.Services
153+
.AddAuthentication(options =>
154+
{
155+
options.DefaultAuthenticateScheme = "MyOwinScheme";
156+
options.DefaultChallengeScheme = "MyOwinScheme";
157+
})
158+
.AddOwinAuthentication("MyOwinScheme", (owinApp, services) =>
159+
{
160+
owinApp.UseMyOwinAuthenticationMiddleware();
161+
});
162+
```
163+
164+
For more information about authentication schemes and how they work in ASP.NET Core, see <xref:security/authentication/index> and <xref:security/authentication/cookie>.
165+
166+
### Access OWIN authentication
167+
168+
Continue using the OWIN `IAuthenticationManager` interface:
169+
170+
```csharp
171+
var authManager = HttpContext.GetOwinContext().Authentication;
172+
173+
authManager.SignIn(identity);
174+
authManager.SignOut();
175+
```
176+
177+
### <xref:System.Security.Claims.ClaimsPrincipal.Current?displayProperty=nameWithType>
178+
179+
If code is expecting to use <xref:System.Security.Claims.ClaimsPrincipal.Current?displayProperty=nameWithType>, then see <xref:migration/fx-to-core/areas/claimsprincipal-current> for options to enable setting that property.
180+
181+
## Migrating ASP.NET Framework Identity
182+
183+
A common migration scenario involves ASP.NET Framework Identity with OWIN cookie authentication. This example shows how to maintain compatibility during migration.
184+
185+
### Configure data protection
186+
187+
Configure data protection to match ASP.NET Framework settings for cookie sharing:
188+
189+
```csharp
190+
var builder = WebApplication.CreateBuilder(args);
191+
192+
var sharedApplicationName = "CommonMvcAppName";
193+
builder.Services.AddDataProtection()
194+
.PersistKeysToFileSystem(new DirectoryInfo(Path.Combine(Path.GetTempPath(), "sharedkeys", sharedApplicationName)))
195+
.SetApplicationName(sharedApplicationName);
196+
```
197+
198+
### Configure OWIN authentication
199+
200+
Set up OWIN authentication with Identity services:
201+
202+
```csharp
203+
builder.Services
204+
.AddAuthentication()
205+
.AddOwinAuthentication("AppAuthenticationScheme", (app, services) =>
206+
{
207+
app.CreatePerOwinContext(ApplicationDbContext.Create);
208+
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
209+
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
210+
211+
var dataProtector = services.GetDataProtector(
212+
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
213+
"AppAuthenticationScheme",
214+
"v2");
215+
216+
app.UseCookieAuthentication(new CookieAuthenticationOptions
217+
{
218+
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
219+
LoginPath = new PathString("/Account/Login"),
220+
Provider = new CookieAuthenticationProvider
221+
{
222+
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
223+
validateInterval: TimeSpan.FromMinutes(30),
224+
regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
225+
},
226+
CookieName = ".AspNet.ApplicationCookie",
227+
TicketDataFormat = new AspNetTicketDataFormat(new DataProtectorShim(dataProtector))
228+
});
229+
});
230+
```
231+
232+
### Use in controllers
233+
234+
Access OWIN-registered services in controllers:
235+
236+
```csharp
237+
using Microsoft.AspNet.Identity.Owin;
238+
using Microsoft.AspNetCore.Mvc;
239+
using Microsoft.AspNetCore.SystemWebAdapters;
240+
using Microsoft.Owin.Security;
241+
242+
[Authorize]
243+
public class AccountController : Controller
244+
{
245+
public ApplicationSignInManager SignInManager =>
246+
HttpContext.GetOwinContext().Get<ApplicationSignInManager>();
247+
248+
public ApplicationUserManager UserManager =>
249+
HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
250+
251+
private IAuthenticationManager AuthenticationManager =>
252+
HttpContext.GetOwinContext().Authentication;
253+
254+
[HttpPost]
255+
[ValidateAntiForgeryToken]
256+
public async Task<IActionResult> Login(LoginViewModel model)
257+
{
258+
var result = await SignInManager.PasswordSignInAsync(
259+
model.Email,
260+
model.Password,
261+
model.RememberMe,
262+
shouldLockout: false);
263+
264+
if (result == SignInStatus.Success)
265+
{
266+
return RedirectToAction("Index", "Home");
267+
}
268+
269+
ModelState.AddModelError("", "Invalid login attempt.");
270+
return View(model);
271+
}
272+
273+
[HttpPost]
274+
[ValidateAntiForgeryToken]
275+
public IActionResult Logout()
276+
{
277+
AuthenticationManager.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
278+
return RedirectToAction("Index", "Home");
279+
}
280+
}
281+
```
282+
283+
### Key configuration points
284+
285+
When migrating ASP.NET Framework Identity:
286+
287+
* **Data protection**: Configure the same `ApplicationName` and key storage location in both ASP.NET Framework and ASP.NET Core
288+
* **Per-request services**: Use `app.CreatePerOwinContext<T>()` to register services created once per request
289+
* **Data protection bridge**: Use `AspNetTicketDataFormat` with `DataProtectorShim` to bridge ASP.NET Core's `IDataProtector` to OWIN
290+
* **Service access**: Access OWIN-registered services through `HttpContext.GetOwinContext()`
291+
* **Cookie names**: Ensure the `CookieName` matches between applications when sharing authentication state
292+
293+
## OWIN pipeline in HttpApplication events
294+
295+
This pattern runs OWIN middleware within the emulated `HttpApplication` event pipeline, similar to how OWIN works in ASP.NET Framework's integrated pipeline mode.
296+
297+
### When to use this pattern
298+
299+
Use this approach when:
300+
301+
* Your application relies on the ASP.NET Framework integrated pipeline
302+
* OWIN middleware needs to execute at specific `HttpApplication` event stages
303+
* You're migrating applications that use both `HttpApplication` events and OWIN together
304+
305+
### Setup
306+
307+
Configure the OWIN pipeline to run within `HttpApplication` events:
308+
309+
```csharp
310+
var builder = WebApplication.CreateBuilder(args);
311+
312+
builder.Services
313+
.AddSystemWebAdapters()
314+
.AddOwinApp(app =>
315+
{
316+
app.UseMyOwinMiddleware();
317+
app.UseStageMarker(PipelineStage.Authenticate);
318+
});
319+
320+
var app = builder.Build();
321+
322+
app.UseSystemWebAdapters();
323+
app.Run();
324+
```
325+
326+
### Access services
327+
328+
Access the `IServiceProvider` when configuring the OWIN pipeline:
329+
330+
```csharp
331+
builder.Services
332+
.AddSystemWebAdapters()
333+
.AddOwinApp((app, services) =>
334+
{
335+
var configuration = services.GetRequiredService<IConfiguration>();
336+
app.UseMyOwinMiddleware(configuration);
337+
app.UseStageMarker(PipelineStage.Authenticate);
338+
});
339+
```
340+
341+
### HttpApplication event mapping
342+
343+
The OWIN pipeline integrates with these `HttpApplication` events:
344+
345+
* `AuthenticateRequest` / `PostAuthenticateRequest`
346+
* `AuthorizeRequest` / `PostAuthorizeRequest`
347+
* `ResolveRequestCache` / `PostResolveRequestCache`
348+
* `MapRequestHandler` / `PostMapRequestHandler`
349+
* `AcquireRequestState` / `PostAcquireRequestState`
350+
* `PreRequestHandlerExecute`
351+
352+
Use `.UseStageMarker(PipelineStage)` to control when OWIN middleware executes relative to these events.
353+
354+
## Migration strategy
355+
356+
When incorporating OWIN middleware into your ASP.NET Core application:
357+
358+
1. **Identify OWIN dependencies**: Determine which OWIN middleware your application uses
359+
1. **Choose integration pattern**: Select the appropriate pattern based on your application's needs
360+
1. **Configure data protection**: Set up shared data protection for authentication cookie sharing
361+
1. **Test authentication flow**: Verify authentication works correctly in the ASP.NET Core application
362+
1. **Gradual conversion**: Plan to migrate OWIN middleware to native ASP.NET Core middleware over time
363+
1. **Monitor compatibility**: Ensure OWIN middleware behavior matches expectations during migration
364+
365+
## Additional resources
366+
367+
* <xref:migration/fx-to-core/areas/authentication>
368+
* <xref:fundamentals/middleware/index>
369+
* <xref:security/authentication/index>

aspnetcore/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,8 @@ items:
21702170
uid: migration/fx-to-core/areas/authentication
21712171
- name: Membership
21722172
uid: migration/fx-to-core/areas/membership
2173+
- name: OWIN
2174+
uid: migration/fx-to-core/areas/owin
21732175
- name: Web API
21742176
uid: migration/fx-to-core/areas/webapi
21752177
- name: ClaimsPrincipal.Current

0 commit comments

Comments
 (0)