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

Некоторое время назад у меня была проблема с плагином 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] ... но я не могу понять, в чем проблема с моим кодом.

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

EDIT :

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

alt text

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

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

РЕДАКТИРОВАТЬ 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 :

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

1 Ответ

1 голос
/ 23 ноября 2010

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

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

...