asp.net-mvcasp.net-coreasp.net-identitydata-protection

Migrate asp.net core Identity to use Data Protection with SQL DB


I have an asp.net core 3.1 MVC application that I have been using the asp.net core Identity. Now I created an API that shares the same source code, including the Identity Services, and also creates users and sends an email with registration tokens to be confirmed. From the registration link, the user is redirected to the MVC Application to complete registration. But the token is always invalid during the registration.

From reading other questions, I saw that adding the Microsoft.AspNetCore.DataProtection package, configure startup class services.AddDataProtection().PersistKeysToDbContext<MyDbContext>();, and creating the migration, would make 2 applications sharing the same instance of "Machine Key".

The configuration is simple and I added it but seems to me that I need to add some keys in other to have the identity working again. After adding the Data protection, my application stops working, and the following error appears, which seems that it does miss some configurations in the table created by DataProtection. Any idea what am I missing here? I never created the Machine key so am a bit lost. :/

An unhandled exception occurred while processing the request.

ArgumentNullException: Value cannot be null. (Parameter 'source')

Microsoft.EntityFrameworkCore.Utilities.Check.NotNull(T value, string parameterName)

CryptographicException: An error occurred while trying to encrypt the provided data. Refer to the inner exception for more information.
Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Protect(byte[] plaintext) System.ArgumentNullException: Value cannot be null. (Parameter 'source') at Microsoft.EntityFrameworkCore.Utilities.Check.NotNull[T](T value, String parameterName) at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsNoTracking[TEntity](IQueryable`1 source) at Microsoft.AspNetCore.DataProtection.EntityFrameworkCore.EntityFrameworkCoreXmlRepository`1.GetAllElements() at Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager.GetAllKeys() at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.CreateCacheableKeyRingCore(DateTimeOffset now, IKey keyJustAdded) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.Microsoft.AspNetCore.DataProtection.KeyManagement.Internal.ICacheableKeyRingProvider.GetCacheableKeyRing(DateTimeOffset now) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.GetCurrentKeyRingCore(DateTime utcNow, Boolean forceRefresh) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingProvider.GetCurrentKeyRing() at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Protect(Byte[] plaintext)

Solution

  • I figure it, I missed adding set; property on DataProtectionKeys in my DbCOntext. public

    DbSet<DataProtectionKey> DataProtectionKeys { get; set; }