I am making JSON-based AJAX requests and using MVC controllers I am very grateful to Phil Haack for Preventing CSRF with AJAX and, Johan Driessen Updated Anti-XSRF for MVC 4 RC . But as I move APIs into Web APIs, I run into problems when the functionality between the two approaches is noticeably different, and I can’t switch to CSRF code.
Scotts recently raised a similar
question , which was
answered by Darin Dimitrov. Darin's solution includes an authorization filter implementation that calls AntiForgery.Validate. Unfortunately, this code does not work for me (see the next paragraph) and, frankly, too advanced for me.
As I understand it, Phil's solution overcomes the problem with MVC AntiForgery when executing JSON requests in the absence of a form element; the form element is supposed / expected using the AntiForgery.Validate method. I believe that this may be because I have problems with Darin’s decision. I get an HttpAntiForgeryException "Required form field to fake" __RequestVerificationToken "no". I am sure the token is POSTED (albeit in the header for the Phil Haack solution). Here's a snapshot of a client call:
$token = $('input[name=""__RequestVerificationToken""]').val(); $.ajax({ url:/api/states", type: "POST", dataType: "json", contentType: "application/json: charset=utf-8", headers: { __RequestVerificationToken: $token } }).done(function (json) { ... });
I tried to hack by combining Johan's solution with Darin and was able to make everything work, but I imagine HttpContext.Current, unsure whether this is suitable / safe and why I can not use the provided HttpActionContext.
Here's my inelegant mash-up .. change is 2 lines in a try block:
public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) { try { var cookie = HttpContext.Current.Request.Cookies[AntiForgeryConfig.CookieName]; AntiForgery.Validate(cookie != null ? cookie.Value : null, HttpContext.Current.Request.Headers["__RequestVerificationToken"]); } catch { actionContext.Response = new HttpResponseMessage { StatusCode = HttpStatusCode.Forbidden, RequestMessage = actionContext.ControllerContext.Request }; return FromResult(actionContext.Response); } return continuation(); }
My questions:
- Do I believe that Darin’s decision assumes the existence of an element of form?
- What is an elegant way to put together a Darin Web API filter with RC Johan MVC 4 code?
Thanks in advance!
asp.net-web-api asp.net-mvc-4 antiforgerytoken
DazWilkin Jul 30 2018-12-12T00: 00Z
source share