防伪令牌无法解密

use*_*122 59 asp.net-mvc asp.net-mvc-4

我有一个表格:

@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl })) {
@Html.AntiForgeryToken()
@Html.ValidationSummary()...
Run Code Online (Sandbox Code Playgroud)

和行动:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl, string City)
{
}
Run Code Online (Sandbox Code Playgroud)

偶尔(每周一次),我收到错误:

防伪令牌无法解密.如果此应用程序由Web场或群集托管,请确保所有计算机都运行相同版本的ASP.NET网页,并且配置指定显式​​加密和验证密钥.AutoGenerate不能在群集中使用.

我尝试添加到webconfig:

<machineKey validationKey="AutoGenerate,IsolateApps"  
    decryptionKey="AutoGenerate,IsolateApps" />
Run Code Online (Sandbox Code Playgroud)

但错误仍然偶尔出现

我注意到发生了这个错误,例如当一个人来自一台计算机然后再尝试另一台计算机时

或者有时一个自动值设置不正确的数据类型,如bool到任何jQuery代码的表单字段整数,请检查它.

Ste*_*ing 122

我刚收到这个错误,在我的情况下,它是由防伪令牌以相同的形式应用两次引起的.第二个实例来自局部视图,因此并不是很明显.

  • 由于页面上的多个防伪标记(注销由 MVC 默认模板中的表单元素包装),我也收到此错误,但是,我正在执行 ajax 回发。然后我意识到我正在调用 $('form').serialize() 并将其更改为 $('#my-form-id').serialize()。 (2认同)
  • 我认为只要只有一个被传递给表单,页面有两个令牌就可以了。检查生成的 HTML 源代码并确保页面上的每个表单只有一个包含防伪标记的隐藏字段。在生成的页面源中搜索 __RequestVerificationToken。 (2认同)

Dom*_*ind 24

的validationKey = "自动生成"

这告诉ASP.NET生成一个新的加密密钥,用于在每次应用程序启动时加密诸如身份验证票证和防伪令牌之类的内容.如果您收到使用其他密钥(例如在重新启动之前)加密请求项(例如验证cookie)的请求,则可能发生此异常.

如果您远离"AutoGenerate"并专门指定它(加密密钥),那么依赖于该密钥的请求将被正确解密,验证将从应用程序重新启动到重新启动.例如:

<machineKey  
validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75D7
               AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281B"           
decryptionKey="ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719F"
validation="SHA1"
decryption="AES"
/>
Run Code Online (Sandbox Code Playgroud)

您可以在MSDN页面上阅读您的内容:如何:在ASP.NET中配置MachineKey


log*_*al8 11

只需<machineKey .../>从框架版本的链接生成标记,<system.web><system.web/>如果不存在,则插入到Web.config中.

希望这可以帮助.


ram*_*s03 10

如果您从Google那里获得了自己的开发人员计算机显示此错误的信息,请尝试在浏览器中清除Cookie。清除浏览器cookie对我有用。


Pus*_*ots 7

如果您使用 Kubernetes 并且您的应用程序有多个 pod,这很可能会导致请求验证失败,因为生成 RequestValidationToken 的 pod 不一定是在 POST 回应用程序时验证令牌的 pod。解决方法应该是配置您的 nginx-controller 或您正在使用的任何入口资源,并告诉它进行负载平衡,以便每个客户端都使用一个 pod 进行所有通信。

更新:我设法通过在入口中添加以下注释来修复它:

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
Run Code Online (Sandbox Code Playgroud)


D.L*_*MAN 6

在asp.net Core 中,您应该设置数据保护系统。我在 Asp.Net Core 2.1 或更高版本中进行测试。

有多种方法可以做到这一点,您可以在配置数据保护和替换 ASP.NET Core 中的 ASP.NET machineKey和密钥存储提供程序中找到更多信息。

  • 第一种方式:本地文件(容易实现)

    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));
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)
  • 第二种方式:保存到数据库

    该Microsoft.AspNetCore.DataProtection.EntityFrameworkCore NuGet包必须添加到项目文件

    将MyKeysConnectionConnectionString添加到您的项目 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; }
    }
    
    Run Code Online (Sandbox Code Playgroud)

    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();
       }
    }
    
    Run Code Online (Sandbox Code Playgroud)