6

I would like to share an authentication cookie provided by the ASP.NET Framework app and use it in ASP.NET Core app. To encrypt cookie I am using Data Protection, which is a default in .NET Core and requires package Microsoft.AspNetCore.DataProtection.SystemWeb for .NET Framework.

When .NET Core generates and protects cookie authentication works for .NET Core app. When .NET Framework generates and protects cookie .NET Core app doesn't use it.

According to https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/compatibility/replacing-machinekey?view=aspnetcore-3.1 properly protected cookie should start with "CfDJ8", which is the base64 representation of the magic "09 F0 C9 F0" header that identifies a payload protected by the data protection system. The cookie generated by .NET Core starts with "CfDJ8" but cookie generated by .NET Framework starts with "09F0C9F0". It seems that cookie is correctly generated and protected but .NET Core uses base64 to encode cookie and .NET Framework uses hexadecimal strings.

The question is, how to set up common cookie encoding for an authentication cookie encrypted by ASP.NET Core Data Protection?

Marek
  • 81
  • 1
  • 4

3 Answers3

1

I followed the guide here to share cookie between as .NET framework Webforms application and a newer aspnetcore 5 application.

https://learn.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-5.0

In my case, the webforms app authenticates and issues the cookie. I see that the cookie is generated and set correctly with the encrypted header text indicating the Data Protection system is in effect (see the screenshot below).

enter image description here

The webforms app works fine, however the aspnetcore app does not use this cookie! Any action with [Authorize] attribute is taken back to the login page. Is there anything else that needs to be done on the aspnet core side to make this work?

Shreedhar Kotekar
  • 1,034
  • 10
  • 20
  • I figured out what was wrong. The linked guide is accurate and I had made a typo in the purpose string used for creating IDataProtector. Instead of `protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Identity.Application", "v2")` I had used "V2" as the last parameter with a capital V. Once I fixed that, it is working flawlessly. – Shreedhar Kotekar Feb 05 '21 at 00:37
  • https://learn.microsoft.com/en-us/aspnet/core/security/cookie-sharing?view=aspnetcore-6.0 – cskwg Dec 16 '21 at 06:07
0

I followed the guide at https://github.com/blowdart/idunno.CookieSharing and it worked perfectly. The guide is far more in depth than this answer. As a summary, you want to use DataProtector in both apps, with Microsoft.Owin.Security.Interop.DataProtectorShim enabling DataProtector to work in the .Net Framework App and Microsoft.Owin.Security.Interop.AspNetTicketDataFormat providing the ticket format for the .Net Framework App :

.NET Core

  • Use Data Protection (OP is already doing so)
  • For consistency (and to ensure implementations match), set your TicketDataFormat explicitly

So, something like this:

var protectionProvider = DataProtectionProvider.Create(
    new DirectoryInfo("c:\keyring"));
var dataProtector = protectionProvider.CreateProtector(
    "CookieAuthenticationMiddleware","Cookie","v2");
var ticketFormat = new TicketDataFormat(dataProtector);
services.ConfigureApplicationCookie(options =>
{
    options.TicketDataFormat = ticketFormat;
    //...
});

.Net Framework

  • Use Data Protection

  • For consistency (and to ensure implementations match), set your TicketDataFormat explicitly.

  • Add the Microsoft.Owin.Security.Interop nuget package. You'll need it to wrap your DataProtector in a DataProtectorShim (and explicitly use the AspNetTicketDataFormat interop class).

    var cookieOptions = new CookieAuthenticationOptions
    {
        TicketDataFormat = ticketFormat,
        //...
    };
    
    var protectionProvider = DataProtectionProvider.Create(
        new DirectoryInfo("c:\keyring"));
    var dataProtector = protectionProvider.CreateProtector(
     "CookieAuthenticationMiddleware", "Cookie", "v2");
    var ticketFormat = new AspNetTicketDataFormat(
       new DataProtectorShim(dataProtector));
    
Brian
  • 25,523
  • 18
  • 82
  • 173
-1

You should use data protection API in classic asp.net. To achieve this you can refer to below steps or direct check this Document

To share authentication cookies between two different ASP.NET 5 applications, configure each application that should share cookies as follows.

Install the package Microsoft.AspNet.Authentication.Cookies.Shareable into each of your ASP.NET 5 applications. In Startup.cs, locate the call to UseIdentity, which will generally look like the following.

// Add cookie-based authentication to the request pipeline.
app.UseIdentity();

Remove the call to UseIdentity, replacing it with four separate calls to UseCookieAuthentication. (UseIdentity calls these four methods under the covers.) In the call to UseCookieAuthentication that sets up the application cookie, provide an instance of a DataProtectionProvider that has been initialized to a key storage location.

// Add cookie-based authentication to the request pipeline.
// NOTE: Need to decompose this into its constituent components
// app.UseIdentity();

app.UseCookieAuthentication(null, IdentityOptions.ExternalCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorRememberMeCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.TwoFactorUserIdCookieAuthenticationScheme);
app.UseCookieAuthentication(null, IdentityOptions.ApplicationCookieAuthenticationScheme,
    dataProtectionProvider: new DataProtectionProvider(
        new DirectoryInfo(@"c:\shared-auth-ticket-keys\")));

Caution: When used in this manner, the DirectoryInfo should point to a key storage location specifically set aside for authentication cookies. The application name is ignored (intentionally so, since you’re trying to get multiple applications to share payloads). You should consider configuring the DataProtectionProvider such that keys are encrypted at rest, as in the below example.

app.UseCookieAuthentication(null, IdentityOptions.ApplicationCookieAuthenticationScheme,
  dataProtectionProvider: new DataProtectionProvider(
      new DirectoryInfo(@"c:\shared-auth-ticket-keys\"),
      configure =>
      {
          configure.ProtectKeysWithCertificate("thumbprint");
      }));

The cookie authentication middleware will use the explicitly provided implementation of the DataProtectionProvider, which due to taking an explicit directory in its constructor is isolated from the data protection system used by other parts of the application.

Asp.net will use dataprotection which is injected by DI to encrypt cookies, in that case you need to enable owin auth in your classic asp.net application.