I have the following form:
<form asp-action="GetUsersAPICall" asp-controller="UsersObject" asp-antiforgery="true" data-ajax="true" data-ajax-method="get" data-ajax-mode="replace" data-ajax-update="#userSearchResult">
Enter email or name to search for: <input type="text" id="query" name="query"/>
<input type="submit" value="Search" />
</form>
<div id="userSearchResult"></div>
(Yes, I do realize that I'm kind of mixing Unobtrusive AJAX syntax with ASP.NET Core tag helpers).
I have the following Action Method in my controller:
[HttpPost]
[Authorize(Roles = "PatchUser")]
//[ValidateAntiForgeryToken]
public async Task<IActionResult> PatchUserAPICall(UserPatchViewModel vm)
{
if (vm == null)
{
return BadRequest();
}
else if (!ModelState.IsValid)
{
return View(vm);
}
else
{
bool result = await vm.User.Update();
if (result)
{
return RedirectToAction("Confirmation");
}
else
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
}
}
This works just fine, unless I uncomment the ValidateAntiForgeryToken
attribute.
I've seen examples of doing validation for jQuery AJAX calls, but many of those rely on sending it in the headers (e.g. in this Q&A). Supposedly, this will make the ValidateAntiForgeryToken
just work as expected (with a few configuration changes in code). Hopefully I'm not missing something obvious, but I've searched quite a bit and can't find how to actually add a header in Unobtrusive AJAX, so I haven't even be able to try something like that to see if it would work.
I know that you can do User.IsInRole("RoleName")
as an alternative to the Authorize
attribute. Is there a way to send the Anti-Forgery Token as a parameter and do it that way? Or is there a way to edit the headers and do it that way? Or is there a better way to do this that I haven't thought of yet?
In general, is there some way to edit the Ajax call before it's sent?