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?
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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With