Configure .Net Core Data Protection for Load Balancers
Problem
I was using Cookie Authentication (without Identity), containing application deployed over multiple servers under load balancers, runs into problem that generates your authentication cookie will not get shared across servers, as by default each server generates its own Data Protection Keys which could not be shared among servers that results into Unauthorized or Invalid authentications.
By default, ASP.NET Core’s data protection isolates applications based on file paths, or IIS hosting information, so multiple apps can share a single keyring, but still not be able to read each other’s data. Source
Solution
ASP.NET Core’s Data Protection must share the same key ring and app identifier for each instance of your application. This means if you are load balanced across multiple machines, you must configure ASP.NET Core’s Data Protection, either protecting the keys over shared File System or DB and also provides mechanism of encryption & decryption.
The ASP.NET Core data protection provides a cryptographic API to protect data, including key management and rotation (including the necessary mechanisms for encryption and decryption)
- Configure SetApplicationName in each app with the same value.
- Could Persists Keys to File System.
- Could Persists Keys to DB.
- Could Encrypt Keys using X.509 certificate.
Add Data Protection
Add Data Protection in ConfigureServices of Startup.cs file
builder.Services.AddDataProtection()
Configure Application Name
Configure Unique name of the application.
services.AddDataProtection().SetApplicationName(“SharedApplicationName”);
Persists Keys to File System
To configure a file system-based key repository, call the PersistKeysToFileSystem configuration routine as shown below. Provide a DirectoryInfo pointing to the repository where keys should be stored.
services.AddDataProtection().SetApplicationName(“SharedApplicationName”).PersistKeysToFileSystem(new DirectoryInfo(@”c:\temp-keys\”));
The File System can point to a directory on the local machine, or it can point to a folder on a network share.
Consider using an X.509 certificate to encrypt keys
Persists Keys to Database using Entity Framework Core
The Microsoft.AspNetCore.DataProtection.EntityFrameworkCore package provides a mechanism for storing data protection keys to a database using Entity Framework Core. With this package, keys can be shared across multiple instances of a web app.
services.AddDbContext<DataProtectionKeysContext>(options =>options.UseSqlServer(Configuration.GetConnectionString(“DataProtectionKeysConnection”)));
services.AddDataProtection().SetApplicationName(“SharedApplicationName”).PersistKeysToDbContext<DataProtectionKeysContext>();
public class DataProtectionKeysContext : DbContext, IDataProtectionKeyContext {public DataProtectionKeysContext(DbContextOptions<DataProtectionKeysContext> options) : base(options) { } public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } }
Create DataProtectionKeys table
Run the application & check Data Protection key in DB. It will automatically create new key after 90 days or you can also customize it.
That's all for this article.
Happy Coding!!
References