I've lost at least 2 full working days on this and have tried numerous ways to achieve this without success.
The scenario is like this: I have 2 applications deployed to Azure, let's say they are backoffice.website.com
and frontoffice.website.com
. Both are 2 separate Azure web apps. A user who logs in to backoffice.website.com
should be able to go to a list of users that have logins at frontoffice.website.com
and select a user to impersonate, which would redirect them to frontoffice.website.com
, logged in as the selected user.
Both websites use the same database in Azure and share the same DbContext
(both projects live in the same solutions in Visual Studio and both reference the same data access layer, which points to the database for both applications (both applications use the same .Net Core Identity setup and tables)
Now, according to the article here.
You should be able to set up Startup.ConfigureServices
method to look something like this:
app.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";
var protectionProvider = DataProtectionProvider.Create(new DirectoryInfo(@"c:\shared-auth-ticket-keys\"));
options.Cookies.ApplicationCookie.DataProtectionProvider = protectionProvider;
options.Cookies.ApplicationCookie.TicketDataFormat = new TicketDataFormat(protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2"));
});
And this works, locally using IIS Express, but in Azure, there is no directory access outside of the application that all applications in an Azure account can share (that I know of, and yes, I know they have other options for file sharing, but we'll get to that now).
Since we can't use a directory to place the file that has the shared key needed between 2 applications in a directory in Azure,
We refer to this article here, which leads to creating a Blob container in Azure to store the key in so that any and all apps I desire to create and host in Azure can access the key from the store.
Using bits from the first referenced article and the 2nd, the code now looks something like this (set all in the Startup.ConfigureServices
method for readability):
var storageAccount = new CloudStorageAccount(
new StorageCredentials("blob", "SASKeyHere"),
new StorageUri(new Uri("https://endpoint.blob.core.windows.net/")),
null,
null,
null
);
var client = storageAccount.CreateCloudBlobClient();
var container = client.GetContainerReference("container");
container.CreateIfNotExistsAsync().GetAwaiter().GetResult();
var serviceCollection = new ServiceCollection();
serviceCollection.AddDataProtection().PersistKeysToAzureBlobStorage(container, "fileName.xml");
var service2 = serviceCollection.BuildServiceProvider();
var dataProtector = service2.GetRequiredService<IDataProtectionProvider>();
// Add framework services.
services.AddDbContext<DbContext>(options => options
.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddIdentity<ApplicationUser, IdentityRole>(options =>
{
options.Cookies.ApplicationCookie.AuthenticationScheme = "ApplicationCookie";
var protectionProvider = dataProtector;
options.Cookies.ApplicationCookie.DataProtectionProvider = protectionProvider;
options.Cookies.ApplicationCookie.TicketDataFormat = new TicketDataFormat(protectionProvider.CreateProtector("Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationMiddleware", "Cookies", "v2"));
})
.AddEntityFrameworkStores<DbContext>()
.AddDefaultTokenProviders();
This ALSO works locally! This code is in the ConfigureServices
method for both applications and lets the cookies be read across both applications, But once deployed, does not work!
Has anyone been able to achieve this or something similar?!