Я делаю запросы AJAX на основе JSON и с помощью MVC-контроллеров очень благодарен Phil Haack за его Предотвращение CSRF с AJAX и, Johan Driessen Обновлен Anti-XSRF для MVC 4 RC. Но по мере перехода API-ориентированных контроллеров в Web API я сталкиваюсь с проблемами, когда функциональность между этими двумя подходами заметно отличается, и я не могу перейти на код CSRF.
Скоттс недавно поднял аналогичный question, который был ответил Дарином Димитровым. Решение Darin включает в себя реализацию фильтра авторизации, который вызывает AntiForgery.Validate. К сожалению, этот код не работает для меня (см. Следующий абзац) и, честно говоря, слишком продвинутый для меня.Как я понимаю, решение Фила преодолевает проблему с MVC AntiForgery при выполнении запросов JSON в отсутствие элемента формы; элемент формы предполагается/ожидаемым с помощью метода AntiForgery.Validate. Я считаю, что это может быть и потому, что у меня проблемы с решением Дарина. Я получаю исключение HttpAntiForgeryException "Необходимое поле формы для подделки" __RequestVerificationToken "нет". Я уверен, что токен POSTED (хотя и в заголовке для решения Phil Haack). Здесь снимок клиентского вызова:
$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) {
...
});
Я попробовал взломать, объединив решение Johan с Дарином и смог заставить все работать, но представляю HttpContext.Current, неуверенный, является ли это подходящим/безопасным и почему я не могу использовать предоставленный HttpActionContext.
Здесь мое неэлегантное mash-up.. изменение - это 2 строки в блоке try:
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();
}
Мои вопросы:
- Правильно ли я полагаю, что решение Дарина предполагает существование элемента формы?
- Какой элегантный способ скомпоновать фильтр Darin Web API с кодом RC Johan MVC 4?
Спасибо заранее!