Problem with ASP.NET Core Identity with Docker

Hello everyone,
I have a problem with Docker that I don't encounter locally with an application I made with Radzen Blazor Studio, to see if the problem came from my application I redid a basic application with the following options:

  • Blazor Web Application in .Net 8
  • PostgreSQL database
  • Security: ASP.NET Core Identity

I added the DockerFile and the same network as my database in Docker in the launchSettings.json.

On the first launch with docker, I got these warnings and this error:

warn: Microsoft.AspNetCore.DataProtection.Repositories.EphemeralXmlRepository[50]
      Using an in-memory repository. Keys will not be persisted to storage.
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[59]
      Neither user profile nor HKLM registry available. Using an ephemeral key repository. Protected data will be unavailable when application exits.

...

info: System.Net.Http.HttpClient.TestIDRadzen2.ClientHandler[100]
      Sending HTTP request POST https://localhost:32789/Account/CurrentUser
fail: Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery[7]
      An exception was thrown while deserializing the token.
      Microsoft.AspNetCore.Antiforgery.AntiforgeryValidationException: The antiforgery token could not be decrypted.
       ---> System.Security.Cryptography.CryptographicException: The key {a68f1806-272b-4b3c-881c-21d08e1e27d4} was not found in the key ring. For more information go to https://aka.ms/aspnet/dataprotectionwarning
         at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status)
         at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData)
         at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
         --- End of inner exception stack trace ---
         at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken)
         at Microsoft.AspNetCore.Antiforgery.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext)

So I added a DataProtection table like this:

dotnet build
dotnet ef migrations add DataProtectionKeys --context TestIDRadzenModelContext
dotnet ef database update --context TestIDRadzenModelContext

I imported via Nugget the package: Microsoft.AspNetCore.DataProtection.EntityFrameworkCore
In my program.cs, after the Context declaration, I added this line:
builder.Services.AddDataProtection().PersistKeysToDbContext<TestIDRadzenModelContext>();
Then in the context, I added the IDataProtectionKeyContext interface and the following code:

public partial class TestIDRadzenModelContext : DbContext, IDataProtectionKeyContext
{
    //Generated code
    public DbSet<DataProtectionKey> DataProtectionKeys { get; set; }
    //Generated code
}

Here's the data I have in my table DataProtectionKeys:

Id: 2
FriendlyName: "key-688712eb-5084-42b4-8e57-0f934d235509"
Xml: "<key id=""688712eb-5084-42b4-8e57-0f934d235509"" version=""1""><creationDate>2024-08-30T12:10:38.4645955Z</creationDate><activationDate>2024-08-30T12:10:38.3641124Z</activationDate><expirationDate>2024-11-28T12:10:38.3641124Z</expirationDate><descriptor deserializerType=""Microsoft.AspNetCore.DataProtection.AuthenticatedEncryption.ConfigurationModel.AuthenticatedEncryptorDescriptorDeserializer, Microsoft.AspNetCore.DataProtection, Version=8.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60""><descriptor><encryption algorithm=""AES_256_CBC"" /><validation algorithm=""HMACSHA256"" /><masterKey p4:requiresEncryption=""true"" xmlns:p4=""http://schemas.asp.net/2015/03/dataProtection""><!-- Warning: the key below is in an unencrypted form. --><value>dGuJBqIgN0mlCxPcSy4T9G6EtClRflcuEj9lOrzW8TJwni8aUUnq7eWABZ47VoI4ylMGiK2X2gDbaeNWAmCRhg==</value></masterKey></descriptor></descriptor></key>"

Don't worry about double “” it's a copy/paste problem.

Now I have no more errors and warnings, but I still can't authenticate myself.
I tried to follow what was in this topic but it did not help me :

I've tried to describe my problem in as much detail as possible. And to put everything I'd added compared to the basic version generated by Radzen. If you need more information, don't hesitate to ask.

Thanks in advance to anyone who can help me.

Unfortunately I see this problem for the first time and don't know what could be causing it. We have been using a similar setup in production for year and a half now (ASP.NET Identity security in Radzen Blazor Studio created app hosted in docker) so there isn't a generic Docker incompatibility.

You can check the following threads as well:

Hello,
I've added the following lines as in your first link:

  1. Remove the [HttpPost] attribute from the CurrentUser method in AccountController.cs
  2. Change the request method in SecurityService.GetAuthenticationStateAsync to HttpMethod.Get
  3. Test again with this change

I went to https://localhost:32807/Account/CurrentUser and I'm logged in:

{
  "isAuthenticated": true,
  "name": "admin",
  "claims": [
    {
      "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
      "value": "2a5c0d02-50c8-45f5-8175-1ad8a224162e"
    },
    {
      "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
      "value": "admin"
    },
    {
      "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
      "value": "admin"
    },
    {
      "type": "AspNet.Identity.SecurityStamp",
      "value": "724a87b3-f1b8-4bbd-8e56-0752f60f8ddf"
    },
    {
      "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name",
      "value": "admin"
    },
    {
      "type": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
      "value": "admin"
    }
  ]
}

I also put a breakpoint in the App.razor to go to the HttpContext and look at: ClaimsPrincipal User. Here too I'm identified. So why do I go back to the login page every time?
Do you have any project sources with ASP.NET Core Identity that work with Docker?
Thank you for your time

Check if HTTPS redirection works as expected. Sometimes this is the problem.

The one we are using in production doesn't have any modifications from the default template.

I'm going to add a comment here in the hope it helps others.... I spent a good while trying to get ASP.NET Identity working within a container, and had the same issues as OP, in particular a login loop. In order to simplify the troubleshooting I created a demo web assembly app using Radzen Blazor Studio, added SQLite data source, and added security. I created a simple docker-compose.yml with two services: the radzen demo app, and also nginx as the reverse proxy. Running the docker compose lead to the dreaded infinite login loop, as described by others. I used AI tools to help troubleshoot, but none of the suggestions worked. Some of the suggestions were good, such as Persisting Data Protection Keys so that auth cookies stay valid across container restarts. There was also an issue with redirects to "~/" instead of just "/". But in the end, what solved the login loop was the demo app (and my own app) had [Authorize] on "/". The first request to "/" has [Authorize], so is challenged and 302'ed to /Login. Then after credentials are posted, the server sets the cookie and redirects back to "/", but before any client-side code runs, the server tries to prerender "/" and hits [Authorize] and voila an infinite loop back to "/login". The fix was to [AllowAnonymous] on "/" and protect whatever content you need protecting with AuthorizeView. Hope this helps others. I'm still not sure why this is such an issue when running in a container vs simply running on a Unix server with a nginx reverse proxy (which works just fine).