14

I am getting the error in my log. I spent most of my day finding the solution but could not find the one which meets my requirement.

Here is the log error

severity=[ERROR], ipaddress=xxxx, subprocess=Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery, description=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 {xxxxxxxxxx} was not found in the key ring. at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.UnprotectCore(Byte[] protectedData, Boolean allowOperationsOnRevokedKeys, UnprotectStatus& status) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.DangerousUnprotect(Byte[] protectedData, Boolean ignoreRevocationErrors, Boolean& requiresMigration, Boolean& wasRevoked) at Microsoft.AspNetCore.DataProtection.KeyManagement.KeyRingBasedDataProtector.Unprotect(Byte[] protectedData) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgeryTokenSerializer.Deserialize(String serializedToken) at Microsoft.AspNetCore.Antiforgery.Internal.DefaultAntiforgery.GetCookieTokenDoesNotThrow(HttpContext httpContext)

    "Certificates": {
    "StoreName": "My",
    "StoreLocation": "LocalMachine"
    "SerialNumber": "xxxxxxxxxxxx"
},
   
   private X509Certificate2 LCertificate()
    {
        var storeName = Configuration["Certificates:StoreName"];
        var storeLocation = Configuration["Certificates:StoreLocation"];
        string serialNumber = Configuration["Certificates: SerialNumber"];
        using(X509Store store = new X509Store(storeName,storeLocation))
        {
            var certificates = store.Certificates
                                    .Find(X509FindType.FindBySerialNumber,
                                          serialNumber,
                                          acceptValidCertOnly);             

            return certificates[0];
        }
    }
    
     public void ConfigureServices(IServiceCollection services)
    {
        services.AddIdentityServer
                .AddSigningCredential(new X509Certificate2(LCertificate()))
      
    }

   [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Login(LoginModel model)
    {
KeentoLearn
  • 355
  • 1
  • 4
  • 12

1 Answers1

16

If

  • your app is hosted on multiple servers
  • has not configured shared data protection
  • you are not using sticky sessions

this will happen when user requests a page with a form from server A, and later submits the form to server B.

It may also happen on a single IIS server if

  • user requests a page with a form
  • you restart the server
  • user submits the form

Reason for this is that a restart causes a new keyring to load into memory, and the antiforgery key inside the form no longer validate.

The latter case can be fixed in IIS by checking "load user profile" in app pool.

More info.

Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Roar S.
  • 8,103
  • 1
  • 15
  • 37
  • In my case I am using both single IIS server and multiple servers. I am also using sticky session into my application. Also, I have not restarted the server but this issue is intermittent. Sometime I will get the issue and sometime not. Please provide solutions for both scenarios. Thank you – KeentoLearn Aug 17 '20 at 04:45
  • Does this solution works for both single and shared servers? What if I just change `load user profile`? Is there any way around without creating database and writing this much of code. Please guide me. Thank you – KeentoLearn Aug 17 '20 at 09:43
  • 1
    For a single server running IIS, load user profile will suffice. – Roar S. Aug 17 '20 at 09:45
  • And using off-the-shelf solutions is also possible: https://learn.microsoft.com/en-us/aspnet/core/security/data-protection/configuration/overview?view=aspnetcore-3.1 – Roar S. Aug 17 '20 at 11:20
  • If you're doing a "blue-green" deployment into two different folders to achieve "zero downtime" deploys (and then map IIS form one to another) make sure you also set explicit application name: `services.AddDataProtection().SetApplicationName("shared app name");` – Alex from Jitbit Sep 05 '21 at 13:31
  • only enabling sticky sessions is not enough in cases like user spends more time than the persistency cookie expiration period. i think only way to get rid of this error completely is adding data protection service to the application. – fatih Jul 22 '22 at 12:56