首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ASP.NET Core WebAPI:提供的防伪令牌的验证失败。cookie令牌和请求令牌被交换。

问ASP.NET Core WebAPI:提供的防伪令牌的验证失败。cookie令牌和请求令牌被交换。
EN

Stack Overflow用户
提问于 2018-02-01 12:39:04
回答 1查看 865关注 0票数 1

在我的ASP.NET核心2 WebAPI应用程序中,我想使用AntiforgeryToken作为我的POST、PUT和DELETE控制器方法。对于这份文件,我设置了ConfigureServices和Configure方法的Startup类。在客户端,我使用角5及其默认的防伪配置。我不知道问题出在哪里。

这是我的Startup.cs的摘录

代码语言:javascript
复制
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();
    });
    // ...
}

我的控制器都是这样的:

代码语言:javascript
复制
[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
}
EN

回答 1

Stack Overflow用户

发布于 2018-04-21 08:21:21

我遇到了同样的问题,我想我发现了这个问题。

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

options.Cookie.Name在AddAntiforgery 中必须与使用context.Response.Cookies.Append手动设置的cookie不同。

试着改变其中一个的名字,它就能工作了。现在,您将覆盖生成的cookie,该cookie使用options.Cookie.Name名称和tokens.RequestToken值。

您可以注意到开发工具的不同之处。

  • 使用options.Cookie.Name生成的默认令牌被标记为http only (HttpOnly = true)
  • 使用context.Response.Cookies.Append手动附加的令牌标记为HttpOnly = false。

第二种是从JS / read中读取(您可以在JS中读取它,因为HttpOnly=false作为头发送到ajax请求中,并根据无法从JS读取的默认消息进行验证)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48563003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档