[英]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
类的ConfigureServices
和Configure
方法。 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
. AddAntiforgery
的options.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. 您可以在开发人员工具中注意到差异。
options.Cookie.Name
is marked as http only
( HttpOnly = true
) options.Cookie.Name
生成的默认令牌被标记为http only
( HttpOnly = true
) 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.