Search code examples
c#asp.net-coreantiforgerytoken

An exception was thrown while deserializing the token.The antiforgery token could not be decrypted in .Net Core 2.2 application


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)
    {

Solution

  • 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.