@manhng

Welcome to my blog!

Sharing cookies between two asp net core applications

May 14, 2021 12:14

Sharing cookies between two asp net core applications (edit)

https://docs.google.com/document/d/1sG2ysmdpzNSQSj760tnzOvByXcHNl6lAO4bBrGcu1Xo/

https://github.com/dotnet/AspNetCore.Docs/blob/main/aspnetcore/security/cookie-sharing.md

https://docs.microsoft.com/en-us/aspnet/core/security/cookie-sharing?tabs=aspnetcore2x&view=aspnetcore-5.0

  • Cookie sharing
  • Sharing cookies between two asp net core applications 

Share cookies between ASP.NET application and ASP.NET Core application

https://github.com/blowdart/idunno.CookieSharing

https://github.com/manhng83/idunno.CookieSharing

Session Management

https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html

XSS (Cross-Site Scripting)

https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html

Original content

Share authentication cookies between ASP.NET 4.x and ASP.NET Core apps

ASP.NET 4.x apps that 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 in several steps while providing a smooth SSO experience across the site.

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. Although UseCookieAuthentication is obsolete and unsupported for ASP.NET Core apps, calling UseCookieAuthentication in an ASP.NET 4.x app that uses Katana Cookie Authentication Middleware is valid.

An ASP.NET 4.x app must target .NET Framework 4.5.1 or later. Otherwise, the necessary NuGet packages fail to install.

To share authentication cookies between an ASP.NET 4.x app and an ASP.NET Core app, configure the ASP.NET Core app as stated in the Share authentication cookies among ASP.NET Core apps section, then configure the ASP.NET 4.x app as follows.

Confirm that the app's packages are updated to the latest releases. Install the Microsoft.Owin.Security.Interop package into each ASP.NET 4.x app.

Locate and modify the call to UseCookieAuthentication:

  • Change the cookie name to match the name used by the ASP.NET Core Cookie Authentication Middleware (.AspNet.SharedCookie in the example).
  • In the following example, the authentication type is set to Identity.Application.
  • Provide an instance of a DataProtectionProvider initialized to the common data protection key storage location.
  • Confirm that the app name is set to the common app name used by all apps that share authentication cookies (SharedCookieApp in the example).

If not setting http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier and http://schemas.microsoft.com/accesscontrolservice/2010/07/claims/identityprovider, set xref:System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier to a claim that distinguishes unique users.

App_Start/Startup.Auth.cs:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
    AuthenticationType = "Identity.Application",
    CookieName = ".AspNet.SharedCookie",
    LoginPath = new PathString("/Account/Login"),
    Provider = new CookieAuthenticationProvider
    {
        OnValidateIdentity =
            SecurityStampValidator
                .OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                    validateInterval: TimeSpan.FromMinutes(30),
                    regenerateIdentity: (manager, user) =>
                        user.GenerateUserIdentityAsync(manager))
    },
    TicketDataFormat = new AspNetTicketDataFormat(
        new DataProtectorShim(
            DataProtectionProvider.Create("{PATH TO COMMON KEY RING FOLDER}",
                (builder) => { builder.SetApplicationName("SharedCookieApp"); })
            .CreateProtector(
                "Microsoft.AspNetCore.Authentication.Cookies." +
                    "CookieAuthenticationMiddleware",
                "Identity.Application",
                "v2"))),
    CookieManager = new ChunkingCookieManager()
});

System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier =
    "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";

When generating a user identity, the authentication type (Identity.Application) must match the type defined in AuthenticationType set with UseCookieAuthentication in App_Start/Startup.Auth.cs.

Models/IdentityModels.cs:

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(
        UserManager<ApplicationUser> manager)
    {
        // The authenticationType must match the one defined in 
        // CookieAuthenticationOptions.AuthenticationType
        var userIdentity = 
            await manager.CreateIdentityAsync(this, "Identity.Application");

        // Add custom user claims here

        return userIdentity;
    }
}

Share authentication cookies between ASP.NET 4.x and ASP.NET Core apps #21987

https://github.com/dotnet/AspNetCore.Docs/issues/21987

I tried & get it worked as it was described in the original doc

.NET Core:

services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo(Configuration["Identity:DataProtectionDir"]))
.SetApplicationName(Configuration["Identity:ApplicationName"]); services.ConfigureApplicationCookie(options => { options.Cookie.SameSite = SameSiteMode.Strict; options.Cookie.Name = Configuration["Identity:CookieName"]; options.Cookie.Path = Configuration["Identity:CookiePath"]; options.Cookie.Domain = Configuration["Identity:CookieDomain"]; options.Cookie.HttpOnly = true; options.ExpireTimeSpan = TimeSpan.FromMinutes(Int32.Parse(Configuration["Identity:CookieExpirationMinutes"])); options.LoginPath = "/Identity/Account/Login"; options.LogoutPath = "/Identity/Account/Logout"; options.AccessDeniedPath = "/Identity/Account/AccessDenied"; options.SlidingExpiration = true; //options.CookieManager = new ChunkingCookieManager(); //options.TicketDataFormat = new SecureDataFormat<AuthenticationTicket>(new TicketSerializer(), // DataProtectionProvider.Create(new DirectoryInfo(Configuration["Identity:DataProtectionDir"]), // (builder) => { builder.SetApplicationName(Configuration["Identity:ApplicationName"]); }) // .CreateProtector( // "Microsoft.AspNetCore.Authentication.Cookies." + // "CookieAuthenticationMiddleware", // "Identity.Application", // "v2")); });`

.NET 4.6.1:

app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = "Identity.Application",
CookieName = "Identity:CookieName",
CookiePath = "/",
CookieDomain = "localhost",
LoginPath = new PathString("/1"),
Provider = new CookieAuthenticationProvider
{
OnException = ex =>
{
AppLogger.LogExceptionRecursively(ex.Exception.Message, ex.Exception, MethodBase.GetCurrentMethod());
}
},
TicketDataFormat = new AspNetTicketDataFormat(
new DataProtectorShim(
DataProtectionProvider.Create(new DirectoryInfo("d:/dataprotection"),
(builder) => { builder.SetApplicationName("Identity:ApplicationName"); })
.CreateProtector(
"Microsoft.AspNetCore.Authentication.Cookies." +
"CookieAuthenticationMiddleware",
"Identity.Application",
"v2"))),
CookieManager = new ChunkingCookieManager()
}); System.Web.Helpers.AntiForgeryConfig.UniqueClaimTypeIdentifier = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name";`

important to have same app name

Shared cookie between applications with different sheme authentication #1833

https://github.com/aspnet/Security/issues/1833

App 1

services.AddDataProtection()
                .PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyStorageLocation"]))
                .SetApplicationName("SharedCookieApp");

var provider = ActivatorUtilities.GetServiceOrCreateInstance<IDataProtectionProvider>(services.BuildServiceProvider());
var dataProtector = provider.CreateProtector("toto");

services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.Name = ".AspNet.SharedCookie";
                options.DataProtectionProvider = provider;
                options.TicketDataFormat = new TicketDataFormat(dataProtector);
            });

services.AddAuthentication("CustomAuthentification")
                .AddWsFederation(options =>
                {
                    // MetadataAddress represents the Active Directory instance used to authenticate users.
                    options.MetadataAddress = "https://adfs01.gpi.pri/FederationMetadata/2007-06/FederationMetadata.xml";

                    // Wtrealm is the app's identifier in the Active Directory instance.
                    // For ADFS, use the relying party's identifier, its WS-Federation Passive protocol URL:
                    options.Wtrealm = Environment.GetEnvironmentVariable("EXTERNAL_URL");
                });

App 2

services.AddDataProtection()
                .PersistKeysToFileSystem(new DirectoryInfo(Configuration["KeyStorageLocation"]))
                .SetApplicationName("SharedCookieApp");

var provider = ActivatorUtilities.GetServiceOrCreateInstance<IDataProtectionProvider>(services.BuildServiceProvider());
var dataProtector = provider.CreateProtector("toto");

services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(options =>
                {
                    options.Cookie.Name = ".AspNet.SharedCookie";
                    options.DataProtectionProvider = provider;
                    options.TicketDataFormat = new TicketDataFormat(dataProtector);
                }); 

Categories

Recent posts