简体   繁体   English

ASP.NET Core WebAPI:验证所提供的防伪令牌失败。 Cookie令牌和请求令牌已交换

[英]ASP.NET Core WebAPI: Validation of the provided antiforgery token failed. The cookie token and the request token were swapped

In my ASP.NET Core 2 WebAPI application I want to use the AntiforgeryToken for my POST, PUT and DELETE controller methods. 在我的ASP.NET Core 2 WebAPI应用程序中,我想对我的POST,PUT和DELETE控制器方法使用AntiforgeryToken。 Reagrding to this documentation I set up the ConfigureServices and Configure methods of my Startup class. 关于本文档,我设置了Startup类的ConfigureServicesConfigure方法。 On the client side I use Angular 5 and their default configuration for Antiforgery. 在客户端,我将Angular 5及其默认配置用于Antiforgery。 I can't figure out where the problem is. 我不知道问题出在哪里。

Here is a excerpt of my Startup.cs 这是我的Startup.cs的摘录

public void ConfigureServices(IServiceCollection services)
{
    // ...
    services.AddAntiforgery(options =>
    {
        options.Cookie.Name = "XSRF-TOKEN";
        options.HeaderName = "X-XSRF-TOKEN";
        options.FormFieldName = "F-XSFR-TOKEN";
    });
    // ...
}

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IServiceProvider provider, ILogger<Startup> logger, IAntiforgery antiforgery)
{
    // ...
    app.Use(async (context, next) =>
    {
        var tokens = antiforgery.GetAndStoreTokens(context);
        context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false });
        await next();
    });
    // ...
}

My Controllers are all like that one: 我的控制器都是这样的:

[Authorize]
[Route("api")]
public class CarController : Controller
{
    #region Variables
    private readonly DataContext _db;
    private ILogger<CarController> _logger;
    #endregion

    #region Constructor
    public CarController(DataContext db, ILogger<CarController> logger)
    {
        _db = db;
        _logger = logger;
    }
    #endregion

    #region Methods
    [AllowAnonymous]
    [HttpGet("[controller]")]
    public IActionResult Get()
    {
        try
        {
            return Ok(_db.Cars);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.GetHashCode(), ex, ex.Message);
            return BadRequest(ex);
        }
    }

    [HttpPost("[controller]")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Post([FromBody] CreateCar model)
    {
        try
        {
            // Creates a new car.
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.HResult, ex, ex.Message);
            return StatusCode(500, ex);
        }
    }

    [HttpPut("[controller]/{id}")]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Put(int id, [FromBody] UpdateCar model)
    {
        try
        {
            // Updates a car
        }
        catch (Exception ex)
        {
            _logger.LogError(ex.HResult, ex, ex.Message);
            return StatusCode(500, ex);
        }
    }
    #endregion
}

I hit the same problem and I think I found the issue. 我遇到了同样的问题,我想我找到了问题。

TLDR: options.Cookie.Name = "ASP-XSRF-TOKEN"; TLDR: options.Cookie.Name = "ASP-XSRF-TOKEN";

The options.Cookie.Name in the AddAntiforgery has to be different than the cookie you set manually using context.Response.Cookies.Append . AddAntiforgeryoptions.Cookie.Name 必须不同于您使用context.Response.Cookies.Append手动设置的cookie。

Try to change the name of one of them and it will work. 尝试更改其中之一的名称,它将起作用。 Right now you override the generated cookie that is using the options.Cookie.Name name with the tokens.RequestToken value. 现在,您将使用options.Cookie.Name名称和tokens.RequestToken值覆盖生成的cookie。

You can notice the difference in the Developer Tools. 您可以在开发人员工具中注意到差异。

  • The default token generated using options.Cookie.Name is marked as http only ( HttpOnly = true ) 使用options.Cookie.Name生成的默认令牌被标记为http onlyHttpOnly = true
  • The manually attached token using context.Response.Cookies.Append is marked as HttpOnly = false 使用context.Response.Cookies.Append手动附加的令牌被标记为HttpOnly = false

The second one is read from JS/Angular (you can read it in JS because the HttpOnly=false and sent as a header in your ajax requests and validated against the default one that can't be read from JS) 第二个是从JS / Angular读取的(您可以在JS中读取它,因为HttpOnly=false并作为ajax请求中的标头发送,并针对无法从JS读取的默认值进行验证)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 显然是随机错误:“防伪令牌验证失败。防伪 cookie 令牌和请求令牌不匹配。” - Apparently Random Error: "Antiforgery token validation failed. The antiforgery cookie token and request token do not match." ASP.NET Core 3.1 URL 链接到需要授权的页面,给出错误 Antiforgery 令牌验证失败 - ASP.NET Core 3.1 URL link to page that requires authorisation giving error Antiforgery token validation failed 在asp.net核心中发送带有防伪令牌的post ajax请求不访问控制器方法 - Send post ajax request with antiforgery token in asp.net core do not access controller method Asp.NET 核心 3 - Azure Active Directory - 令牌验证失败 - 签名验证失败。 无法匹配密钥 - Asp.NET Core 3 - Azure Active Directory - Token Validation fails - Signature validation failed. Unable to match key 在 ASP.NET 内核中使用 Antiforgery 并得到错误 - 无法解密防伪令牌 - Using Antiforgery in ASP.NET Core and got error - the antiforgery token could not be decrypted ASP.Net Core JWT 令牌验证 - ASP.Net Core JWT Token validation ASP.NET核心网站使用JWT令牌进行WebApi身份验证 - ASP.NET Core Website to WebApi authentication using JWT token 如何在每个ASP.NET WebApi请求上对JWT令牌应用自定义验证? - How to apply custom validation to JWT token on each request for ASP.NET WebApi? asp.net core 2.0部署 - InvalidOperationException:无法解密防伪令牌 - asp.net core 2.0 deployment - InvalidOperationException: The antiforgery token could not be decrypted 在外部消费者(应用程序)中使用 ASP.NET Core 6 Web API Antiforgery Token,无需身份验证 - Using ASP.NET Core 6 Web API Antiforgery Token in extern consumer (App) without Authentication
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM