We have a WebForms application built against ASP.Net Framework (4.7.2) that uses OWIN cookie authentication. As part of a migration towards .Net Core we would like to use the cookies within a .Net Core (2.1) API application.
The WebForms application runs in Azure and leverages DataProtectionStartup
to hook into IServiceCollection
the Machine Key file to use the PersistKeysToAzureBlobStorage
method within Microsoft.AspNetCore.DataProtection
as per the Microsoft documentation.
WebForms DataProtectionStartup
services.AddDataProtection()
.PersistKeysToAzureBlobStorage(blockblob)
.SetApplicationName("OurAppName");
.Net Core API Startup
services.AddDataProtection()
.PersistKeysToAzureBlobStorage(blockblob)
.SetApplicationName("OurAppName");
Both applications are happily running with the machine key generated and stored on blob storage.
Microsoft have
documention
that details how to share an OWIN cookie with a shared machine key file, using the
DataProtectorShim
from Microsoft.Owin.Security.Interop
. The DataProtectionShim
requires a DataProtectionProvider
generated from the shared machine key, in the documentation this is referenced in both applications to create the
cookie and uses the DataProtectionProvider.Create()
method that takes the file location as an argument.
As we are using DataProtection
with blob storage, we do not have this location. We have tried using
DataProtectionProvider.Create()
with just the application name on both applications in that it would use the blob
storage key file. Unfortunately this does not create a cookie that works across both applications.
OWIN cookie authentication settings within OwinStartup
:
app.UseCookieAuthentication(new CookieAuthenticationOptions
{
AuthenticationType = 'Identity.Application',
AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Active,
LoginPath = new PathString("/login.aspx"),
CookieName = "AppCookieName",
ExpireTimeSpan = 300,
SlidingExpiration = true,
Provider = new CookieAuthenticationProvider
{
OnValidateIdentity =
SecurityStampValidator
.OnValidateIdentity<UserManager, User, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) =>
manager.CreateIdentityAsync(user, 'Identity.Application'),
getUserIdCallback: (user) => user.GetUserId<int>())
},
TicketDataFormat = new AspNetTicketDataFormat(
new DataProtectorShim(
DataProtectionProvider.Create("OurAppName")
.CreateProtector(
"Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware",
'Identity.Application',
"v2")
)),
CookieManager = new ChunkingCookieManager()
});
And our .Net Core Startup
setup for cookies:
services.AddAuthentication("Identity.Application")
.AddCookie("Identity.Application", options =>
{
options.Cookie.Name = "AppCookieName";
});
Has anyone come across this scenario before, all the examples we have found only examples of the use of
DataProtectionProvider.Create()
used with machine key file location and have found no guidance for how to accomplish
this with the PersistKeysToAzureBlobStorage
method.
CryptographicException
was burried far, far beneath.. I went as far as replacing most of the Microsoft.Owin.* and Microsoft.AspNetCore.* NuGets with actual git clones to debug, But turning on the Trace logging for these namespaces would have done the same, in hindsight. – Ran Sagy