Токен против подделки не может быть расшифрован
У меня есть форма:
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()...
и действие:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl, string City)
{
}
изредка (раз в неделю) я получаю сообщение об ошибке:
Токен против подделки не может быть расшифрован. Если это приложение размещено на веб-ферме или в кластере, убедитесь, что на всех компьютерах установлена одна и та же версия веб-страниц ASP.NET и что в конфигурации указаны явные ключи шифрования и проверки. Автогенерация не может использоваться в кластере.
я пытаюсь добавить в webconfig:
<machineKey validationKey="AutoGenerate,IsolateApps"
decryptionKey="AutoGenerate,IsolateApps" />
но ошибка все равно иногда появляется
Я заметил, что эта ошибка возникает, например, когда человек пришел с одного компьютера, а затем пытается другой компьютер
Или иногда автоматическое значение, установленное с неверным типом данных, например, bool для целого числа в поле формы любым кодом jQuery, также проверьте это.
14 ответов
Я только что получил эту ошибку, и, в моем случае, она была вызвана тем, что токен против подделки был применен дважды в одной и той же форме. Второй случай исходил от частичного взгляда, поэтому не сразу был очевиден.
validationKey="AutoGenerate"
Это заставляет ASP.NET генерировать новый ключ шифрования для использования при шифровании таких вещей, как аутентификационные билеты и токены защиты от подделки, при каждом запуске приложения. Если вы получили запрос, в котором использовался другой ключ (например, до перезапуска) для шифрования элементов запроса (например, файлов cookie аутентификации), это исключение может возникнуть.
Если вы отойдете от "Автогенерации" и конкретно укажете его (ключ шифрования), запросы, которые зависят от того ключа, будут правильно расшифрованы и проверка будет работать от перезапуска приложения до перезапуска. Например:
<machineKey
validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7
AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"
decryptionKey="ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719F"
validation="SHA1"
decryption="AES"
/>
Вы можете прочитать на свой вкус на странице MSDN: Как: настроить MachineKey в ASP.NET
Просто генерировать <machineKey .../>
пометить ссылку для вашей версии фреймворка и вставить в <system.web><system.web/>
в Web.config, если он не существует.
Надеюсь это поможет.
Если вы пришли сюда из Google для своего компьютера разработчика с этой ошибкой, попробуйте очистить куки в браузере. У меня работали чистые куки браузера.
В asp.net Core необходимо установить систему защиты данных. Я тестирую в Asp.Net Core 2.1 или выше.
есть несколько способов сделать это, и вы можете найти дополнительную информацию в разделе Настройка защиты данных и замена ключа машины ASP.NET в ASP.NET Core и поставщиках хранилища ключей.
первый способ: локальный файл (простая реализация)
Содержание startup.cs:
public class Startup { public Startup(IConfiguration configuration, IWebHostEnvironment webHostEnvironment) { Configuration = configuration; WebHostEnvironment = webHostEnvironment; } public IConfiguration Configuration { get; } public IWebHostEnvironment WebHostEnvironment { get; } // This method gets called by the runtime. // Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // .... Add your services like : // services.AddControllersWithViews(); // services.AddRazorPages(); // ----- finally Add this DataProtection ----- var keysFolder = Path.Combine(WebHostEnvironment.ContentRootPath, "temp-keys"); services.AddDataProtection() .SetApplicationName("Your_Project_Name") .PersistKeysToFileSystem(new DirectoryInfo(keysFolder)) .SetDefaultKeyLifetime(TimeSpan.FromDays(14)); } }
второй способ: сохранить в БД
В
Microsoft.AspNetCore.DataProtection.EntityFrameworkCore
Пакет NuGet необходимо добавить в файл проектаДобавить
MyKeysConnection
ConnectionString к вашим проектам ConnectionStrings вappsettings.json > ConnectionStrings > MyKeysConnection
.Добавить
MyKeysContext
класс к вашему проекту.MyKeysContext.cs содержимое:
public class MyKeysContext : DbContext, IDataProtectionKeyContext { // A recommended constructor overload when using EF Core // with dependency injection. public MyKeysContext(DbContextOptions<MyKeysContext> options) : base(options) { } // This maps to the table that stores keys. public DbSet<DataProtectionKey> DataProtectionKeys { get; set; } }
Содержание startup.cs:
public class Startup { public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } // This method gets called by the runtime. // Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { // ----- Add this DataProtection ----- // Add a DbContext to store your Database Keys services.AddDbContext<MyKeysContext>(options => options.UseSqlServer(Configuration.GetConnectionString("MyKeysConnection"))); // using Microsoft.AspNetCore.DataProtection; services.AddDataProtection() .PersistKeysToDbContext<MyKeysContext>(); // .... Add your services like : // services.AddControllersWithViews(); // services.AddRazorPages(); } }
Если вы используете Kubernetes и имеете более одного модуля для своего приложения, это, скорее всего, приведет к сбою проверки запроса, поскольку модуль, который генерирует RequestValidationToken, не обязательно является модулем, который будет проверять токен при отправке обратно в ваше приложение. Исправление должно состоять в том, чтобы сконфигурировать ваш nginx-контроллер или любой другой используемый вами входной ресурс и указать ему балансировку нагрузки, чтобы каждый клиент использовал один модуль для всех коммуникаций.
Обновление: мне удалось это исправить, добавив следующие комментарии к моему входу:
https://kubernetes.github.io/ingress-nginx/examples/affinity/cookie/
Name Description Values
nginx.ingress.kubernetes.io/affinity Sets the affinity type string (in NGINX only cookie is possible
nginx.ingress.kubernetes.io/session-cookie-name Name of the cookie that will be used string (default to INGRESSCOOKIE)
nginx.ingress.kubernetes.io/session-cookie-hash Type of hash that will be used in cookie value sha1/md5/index
Я столкнулся с этой проблемой в области кода, где у меня было представление, вызывающее частичное представление, однако вместо возвращения частичного представления я возвращал представление.
Я изменился:
возврат View (индекс);
в
вернуть PartialView(index);
под моим контролем, и это решило мою проблему.
Я получил эту ошибку на.NET Core 2.1. Я исправил это, добавив сервис Data Protection в Startup:
public void ConfigureServices(IServiceCollection services)
{
services.AddDataProtection();
....
}
Вы звоните более чем одному @Html.AntiForgeryToken()
на ваш взгляд
Я получаю эту ошибку, когда страница старая ("устаревшая"). Обновление токена через перезагрузку страницы решает мою проблему. Кажется, есть некоторый период ожидания.
Я нашел очень интересный способ решения этой проблемы, по крайней мере, в моем случае. Мое представление динамически загружало частичные представления с формами в div с использованием ajax, все в другой форме. основная форма не представляет проблем, и одна из частей работает, а другая - нет. ЕДИНСТВЕННАЯ разница между частичными представлениями заключалась в том, что в конце рабочего был пустой тег скрипта.
<script type="text/javascript">
</script>
Я удалил его и, конечно же, получил ошибку. Я добавил пустой тег скрипта к другому частичному представлению, и собака его пропустила, все работает! Я знаю, что он не самый чистый ... но что касается скорости и накладных расходов ...
Для тех, кто получает эту ошибку в Google AppEngine или Google Cloud Run, вам необходимо настроить защиту данных вашего веб-сайта ASP.NET Core.
Документация от команды Google проста в использовании и работает.
Общий обзор документов Microsoft можно найти здесь:
Обратите внимание, что вы также можете обнаружить, что вам приходится входить в систему снова и снова, и происходят другие странные вещи. Это все потому, что Google Cloud не выполняет фиксированные сеансы, как это делает Azure, и вы фактически обращаетесь к разным экземплярам с каждым запросом.
Другие зарегистрированные ошибки включают:
Identity.Application was not authenticated. Failure message: Unprotect ticket failed
Я знаю, что немного опоздал на вечеринку, но я хотел добавить еще одно возможное решение этой проблемы. Я столкнулся с той же проблемой в приложении MVC, которое у меня было. Код не менялся большую часть года, и вдруг мы начали получать подобные сообщения об ошибках от приложения.
У нас не было нескольких экземпляров маркера защиты от подделки, примененного к представлению дважды.
У нас на глобальном уровне ключ машины был настроен на автоматическую генерацию из-за требований STIG.
Это раздражало, пока я не получил часть ответа здесь: /questions/11238226/kak-ustranit-isklyuchenie-antiforgerytoken-kotoroe-voznikaet-posle-iisreset-v-moem-prilozhenii-aspnet-mvc/11238261#11238261:
Если для вашего MachineKey установлено значение AutoGenerate, то ваши токены проверки и т. д. не переживут перезапуск приложения — ASP.NET сгенерирует новый ключ при запуске, а затем не сможет правильно расшифровать токены.
Проблема заключалась в превышении лимита частной памяти пула приложений. Это вызвало перезапуск и, следовательно, сделало недействительными ключи для токенов, включенных в форму. Увеличение лимита частной памяти для пула приложений, по-видимому, решило проблему.
Мое исправление заключалось в том, чтобы получить такие значения файлов cookie и токенов:
AntiForgery.GetTokens(null, out var cookieToken, out var formToken);