Проблема Uploadify с токеном аутентификации и Html.AntiforgeryToken (плагин не отправляет куки)

Некоторое время назад у меня была проблема с плагином Uploadify, для которой я нашел решение, описанное в этом ответе.

Проблема в этом вопросе была в основном из-за того, что Uploadify использует флэш-плагин, а флэш-плагин не делит куки-файл аутентификации с кодом на стороне сервера.

Решением было использование пользовательской версии атрибута Authorize (код был опубликован в этом ответе).

Атрибут [TokenizedAuthorize] был помещен в класс контроллера следующим образом

[TokenizedAuthorize]
[CheckForActiveService]
public partial class DocumentController : BaseController
{
}

Несколько дней назад я добавил <%: Html.AntiForgeryToken() %> внутри формы и тому [ValidateAntiForgeryToken] к методу действия, как в следующем примере:

[HttpPost]
[ValidateAntiForgeryToken]
public virtual ActionResult Upload( HttpPostedFileBase fileData ) {
}

В любом случае, я больше не могу загружать файлы на сервер. Используя отладчик, я смог проверить это после последней строки в TokenizedAuthorize код

return base.AuthorizeCore( httpContext );

Я получил исключение, обработанное Эльмой, которое говорит

System.Web.Mvc.HttpAntiForgeryException: invalid or not specified anti forgery token

in System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext filterContext)
in System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext, IList`1 filters, ActionDescriptor actionDescriptor)
in System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext, String actionName)

Это исключение, кажется, подтверждает, что [ValidateAntiForgeryToken] Атрибут вызывается... но я не могу понять, где проблема с моим кодом.

Любая помощь?

РЕДАКТИРОВАТЬ:

Используя отладчик, я проверил значение __RequestVerificationToken параметр формы и, как вы можете видеть, он правильно заполняется значением из <%: Html.AntiForgeryToken() %>

альтернативный текст

РЕДАКТИРОВАТЬ 2:

Я также могу подтвердить, что если я прокомментирую [ValidateAntiForgeryToken] на Post Action все работает как положено

РЕДАКТИРОВАТЬ 3:

Поскольку функция post является вызовом ajax, выполняемым плагином uploadify, AntiForgeryToken добавляется к параметрам записи с помощью небольшой функции js, как в следующем коде.

$('#fileInput').uploadify({
    //other uploadify parameters removed for brevity
    scriptData: AddAntiForgeryToken({ AuthenticationToken: auth }),
});

где AddAntiForgeryToken() это функция javascript, определенная на моей главной странице для поддержки всех сообщений ajax на сервер

<%-- used for ajax in AddAntiForgeryToken() --%>
<form id="__AjaxAntiForgeryForm" action="#" method="post">
    <%: Html.AntiForgeryToken() %>
</form>

// Encapsulate the Anti Forgery Token fetching
AddAntiForgeryToken = function (data) {
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
    return data;
};

РЕДАКТИРОВАТЬ 4:

Darin Dimitrov интуиция верна. Скрипт Uploadify не отправляет куки на сервер, поэтому сервер не может проверить AntiForgeryToken. Как я могу добавить куки в разделе Uploadify scriptData?

1 ответ

Решение

Вы должны убедиться, что cookie с тем же значением, что и __RequestVerificationToken поле отправлено в запросе. Обычно этот файл cookie отправляется Html.AntiforgeryToken() и это должно быть сделано на сервере, потому что его значение зашифровано машинными ключами сервера. Если запрос выполняется Flash-клиентом, я не знаю, отправляет ли он куки-файлы. Если это не так, вам нужно будет отправить его вручную.

Есть также кое-что еще, о чем вы должны знать, и которое вызовет то же исключение, хотя я не думаю, что оно применимо в вашем случае, но стоит проверить. Когда вы используете Html.AntiforgeryToken() помощник, если вошел в систему пользователь, его имя пользователя является частью, если испущенный cookie. Если вы затем попытаетесь POST к действию контроллера, украшенному [ValidateAntiForgeryToken] он проверит, что текущий вошедший в систему пользователь совпадает с тем, когда был создан файл cookie, и, если это не так, вызовет это исключение. Так что я видел, что люди, использующие Html.AntiforgeryToken() сгенерировать некоторые HTML-формы в качестве анонимного пользователя, а затем с помощью AJAX войти в систему пользователя и после входа в систему пользователь отправляет форму - это не удастся.

Другие вопросы по тегам