ASP.NET Core WebAPI: проверка предоставленного токена защиты от подделки завершилась неудачно. Токен cookie и токен запроса были заменены
В моем приложении ASP.NET Core 2 WebAPI я хочу использовать AntiforgeryToken для моих методов контроллера POST, PUT и DELETE. С учетом этой документации я настроил 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
}
1 ответ
Я столкнулся с той же проблемой, и я думаю, что нашел проблему.
TLDR: options.Cookie.Name = "ASP-XSRF-TOKEN";
options.Cookie.Name
в AddAntiforgery
должен отличаться от файла cookie, который вы установили вручную context.Response.Cookies.Append
,
Попробуйте изменить имя одного из них, и оно будет работать. Прямо сейчас вы переопределяете сгенерированный файл cookie, который использует options.Cookie.Name
имя с tokens.RequestToken
значение.
Вы можете заметить разницу в инструментах разработчика.
- Маркер по умолчанию, созданный с использованием
options.Cookie.Name
помечен какhttp only
(HttpOnly = true
) - Прикрепленный вручную токен с помощью
context.Response.Cookies.Append
помечен какHttpOnly = false
Второй читается из JS/Angular (вы можете прочитать его в JS, потому что HttpOnly=false
и отправляется в качестве заголовка в ваших запросах ajax и проверяется на соответствие стандартному, который не может быть прочитан из JS)