9.6 KiB
title | author | description | manager | ms.author | ms.custom | ms.date | ms.prod | ms.technology | ms.topic | uid |
---|---|---|---|---|---|---|---|---|---|---|
Sharing cookies among apps | rick-anderson | Learn how to share authentication cookies among ASP.NET 4.x and ASP.NET Core apps. | wpickett | riande | mvc | 01/19/2017 | asp.net-core | aspnet | article | security/data-protection/compatibility/cookie-sharing |
Sharing cookies among apps
By Rick Anderson and Luke Latham
Websites often consist of individual web apps working together. To provide a single sign-on (SSO) experience, web apps within a site must share authentication cookies. To support this scenario, the data protection stack allows sharing Katana cookie authentication and ASP.NET Core cookie authentication tickets.
View or download sample code (how to download)
The sample illustrates cookie sharing across three apps that use cookie authentication:
- ASP.NET Core 2.0 Razor Pages app without using ASP.NET Core Identity
- ASP.NET Core 2.0 MVC app with ASP.NET Core Identity
- ASP.NET Framework 4.6.1 MVC app with ASP.NET Identity
In the examples that follow:
- The authentication cookie name is set to a common value of
.AspNet.SharedCookie
. - The
AuthenticationType
is set toIdentity.Application
either explicitly or by default. - CookieAuthenticationDefaults.AuthenticationScheme is used as the authentication scheme. The constant resolves to a value of
Cookies
. - The cookie authentication middleware uses an implementation of DataProtectionProvider.
DataProtectionProvider
provides data protection services for the encryption and decryption of authentication cookie payload data. TheDataProtectionProvider
instance is isolated from the data protection system used by other parts of the app.- A common data protection key storage location is used. The sample app uses a folder named KeyRing at the root of the solution to hold the data protection keys.
- DataProtectionProvider.Create(System.IO.DirectoryInfo) accepts a DirectoryInfo for use with authentication cookies. The sample app provides the path of the KeyRing folder to
DirectoryInfo
. - DataProtectionProvider requires the Microsoft.AspNetCore.DataProtection.Extensions NuGet package. To obtain this package for ASP.NET Core 2.0 and later apps, reference the Microsoft.AspNetCore.All metapackage. When targeting .NET Framework, add a package reference to
Microsoft.AspNetCore.DataProtection.Extensions
.
Share authentication cookies among ASP.NET Core apps
When using ASP.NET Core Identity:
ASP.NET Core 2.x
In the ConfigureServices
method, use the ConfigureApplicationCookie extension method to set up the data protection service for cookies.
See the CookieAuthWithIdentity.Core project in the sample code (how to download).
ASP.NET Core 1.x
In the Configure
method, use the CookieAuthenticationOptions to set up:
- The data protection service for cookies.
- The
AuthenticationScheme
to match ASP.NET 4.x.
app.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Cookies.ApplicationCookie.AuthenticationScheme =
"ApplicationCookie";
var protectionProvider =
DataProtectionProvider.Create(
new DirectoryInfo(@"PATH_TO_KEY_RING_FOLDER"));
options.Cookies.ApplicationCookie.DataProtectionProvider =
protectionProvider;
options.Cookies.ApplicationCookie.TicketDataFormat =
new TicketDataFormat(protectionProvider.CreateProtector(
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
"Cookies",
"v2"));
});
When using cookies directly:
ASP.NET Core 2.x
See the CookieAuth.Core project in the sample code (how to download).
ASP.NET Core 1.x
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
DataProtectionProvider =
DataProtectionProvider.Create(
new DirectoryInfo(@"PATH_TO_KEY_RING_FOLDER"))
});
Encrypting data protection keys at rest
For production deployments, configure the DataProtectionProvider
to encrypt keys at rest with DPAPI or an X509Certificate. See Key Encryption At Rest for more information.
ASP.NET Core 2.x
services.AddDataProtection()
.ProtectKeysWithCertificate("thumbprint");
ASP.NET Core 1.x
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
DataProtectionProvider = DataProtectionProvider.Create(
new DirectoryInfo(@"PATH_TO_KEY_RING"),
configure =>
{
configure.ProtectKeysWithCertificate("thumbprint");
})
});
Sharing authentication cookies between ASP.NET 4.x and ASP.NET Core apps
ASP.NET 4.x apps which use Katana cookie authentication middleware can be configured to generate authentication cookies that are compatible with the ASP.NET Core cookie authentication middleware. This allows upgrading a large site's individual apps piecemeal while providing a smooth SSO experience across the site.
[!TIP] When an app uses Katana cookie authentication middleware, it calls
UseCookieAuthentication
in the project's Startup.Auth.cs file. ASP.NET 4.x web app projects created with Visual Studio 2013 and later use the Katana cookie authentication middleware by default.
[!NOTE] An ASP.NET 4.x app must target .NET Framework 4.5.1 or higher. Otherwise, the necessary NuGet packages fail to install.
To share authentication cookies among ASP.NET 4.x apps and ASP.NET Core apps, configure the ASP.NET Core app as stated above, then configure the ASP.NET 4.x apps by following the steps below.
-
Install the package Microsoft.Owin.Security.Interop into each ASP.NET 4.x app.
-
In Startup.Auth.cs, locate the call to
UseCookieAuthentication
and modify it as follows. Change the cookie name to match the name used by the ASP.NET Core cookie authentication middleware. Provide an instance of aDataProtectionProvider
initialized to the common data protection key storage location.
ASP.NET Core 2.x
See the CookieAuthWithIdentity.NETFramework project in the sample code (how to download).
When generating a user identity, the authentication type must match the type defined in AuthenticationType
set with UseCookieAuthentication
.
Models/IdentityModels.cs:
ASP.NET Core 1.x
Set the CookieManager
to interop ChunkingCookieManager
so the chunking format is compatible.
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
CookieName = ".AspNetCore.Cookies",
// CookieName = ".AspNetCore.ApplicationCookie", (if using ASP.NET Identity)
// CookiePath = "...", (if necessary)
// ...
TicketDataFormat = new AspNetTicketDataFormat(
new DataProtectorShim(
DataProtectionProvider.Create(
new DirectoryInfo(@"PATH_TO_KEY_RING_FOLDER"))
.CreateProtector(
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
"Cookies",
"v2"))),
CookieManager = new ChunkingCookieManager()
});
Use a common user database
Confirm that the identity system for each app is pointed at the same user database. Otherwise, the identity system produces failures at runtime when it attempts to match the information in the authentication cookie against the information in its database.