Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Antiforgery in ASP.NET Core and got error - the antiforgery token could not be decrypted

My ASP.Net Core MVC application have added Antiforgery middleware like below:

startup.cs

services.AddMvc();
services.AddSession();
services.AddCaching();
services.AddSession(o =>
{
  o.IdleTimeout = TimeSpan.FromMinutes(120);
});
services.AddAntiforgery();

I've added below in the view and controller

View:

<form action="/Home/Login" method="post" id="staff-login" autocomplete="off">
    @Html.AntiForgeryToken()
 ...

Controller

[HttpPost, ValidateAntiForgeryToken] 
public IActionResult Login(IFormCollection formCollection) 
{...}

The problem is users always get below when users come across different forms.

System.InvalidOperationException: The antiforgery token could not be decrypted. ---> System.Security.Cryptography.CryptographicException: The key {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} was not found in the key ring.

I found a solution which suggests setting a static pair of validation/decryption key in the web.config but it seems this solution is only for classic asp.net application. How should I do in ASP.Net core?

like image 566
seanbun Avatar asked Feb 08 '17 01:02

seanbun


People also ask

How is Antiforgery token validated?

Require antiforgery validationThe ValidateAntiForgeryToken attribute requires a token for requests to the action methods it marks, including HTTP GET requests. If the ValidateAntiForgeryToken attribute is applied across the app's controllers, it can be overridden with the IgnoreAntiforgeryToken attribute.

What is Antiforgery token in C#?

Anti-Forgery Tokens The server includes two tokens in the response. One token is sent as a cookie. The other is placed in a hidden form field. The tokens are generated randomly so that an adversary cannot guess the values.

How is Antiforgery token generated?

AntiForgeryToken() basically generate encrypted value based on the cookie and form data. So if you declare and use this @Html. AntiForgeryToken() for each than it will generate two different _RequestValidationToken. Better declare one global @token variable with @Html.

What does Antiforgery validate do?

Validates that input data from an HTML form field comes from the user who submitted the data. Validates that input data from an HTML form field comes from the user who submitted the data.


2 Answers

I've had exactly that error on a ASP .net core app hosted on a linux container.

From the docs it would seem if you don't meet certain criteria the keys are only persisted in the process - but that even for me was not working.

First the error occurred with the default setup.
I then added specific configuration for the keys on the filesystem:

            services.AddDataProtection()
                .PersistKeysToFileSystem(new System.IO.DirectoryInfo(@"/var/my-af-keys/"));

This also didn't fix the issue I had to set an application name:

            services.AddDataProtection()
                .SetApplicationName("fow-customer-portal")
                .PersistKeysToFileSystem(new System.IO.DirectoryInfo(@"/var/dpkeys/"));

I haven't confirmed but its possible nature of the LXC hosting means .net core cannot persist the identity of the app.

like image 187
ScottC Avatar answered Oct 03 '22 09:10

ScottC


I've had this because I started using the application on a localhost port and then was trying to use it in docker with the same port. By then I had cookies that specified the key generated by my machine, so It wouldn't work on docker.

TL;DR clear your cookies if you ever used that domain/port from other machines.

like image 28
Stefano Avatar answered Oct 03 '22 11:10

Stefano