在我的ASP.NET Core 2 WebAPI应用程序中,我想将AntiforgeryToken用于我的POST,PUT和DELETE控制器方法。重新定位到this documentation我设置了ConfigureServices
课程的Configure
和Startup
方法。在客户端,我使用Angular 5及其Antiforgery的默认配置。我无法弄清楚问题出在哪里。
以下是我的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();
});
// ...
}
我的控制器就像那个:
[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
}
答案 0 :(得分:1)
我遇到了同样的问题,我想我发现了这个问题。
TLDR: options.Cookie.Name = "ASP-XSRF-TOKEN";
options.Cookie.Name
中的AddAntiforgery
必须与您使用context.Response.Cookies.Append
手动设置的Cookie不同。
尝试更改其中一个的名称,它会起作用。现在,您覆盖使用带有options.Cookie.Name
值的tokens.RequestToken
名称生成的Cookie。
您可以注意到开发者工具的不同之处。
options.Cookie.Name
生成的默认令牌标记为http only
(HttpOnly = true
)context.Response.Cookies.Append
的手动附加标记标记为HttpOnly = false
第二个是从JS / Angular中读取的(您可以在JS中读取它,因为HttpOnly=false
并在您的ajax请求中作为标头发送,并针对无法从JS读取的默认值进行验证)