Хорошо, я только что обновил проект до MVC v2.0 здесь, и решение eduncan911 больше не работает, если вы используете AuthorizeAttribute
в своих действиях контроллера. Было довольно сложно понять, почему.
Итак, виновник этой истории в том, что команда MVC добавила использование свойства ViewContext.HttpContext.User.Identity.Name
в значение для RequestVerificationToken
.
Переопределенный OnAuthorization
в базовом контроллере выполняется перед любыми фильтрами в действии контроллера. Таким образом, проблема в том, что атрибут Authorize еще не был вызван и поэтому ViewContext.HttpContext.User
не установлен. Таким образом, UserName является String.Empty, тогда как AntiForgeryToken, используемый для проверки, включает в себя реальное имя пользователя = fail.
Мы решили это сейчас с помощью этого кода:
public abstract class MyBaseController : Controller
{
protected override void OnAuthorization(AuthorizationContext filterContext)
{
//enforce anti-forgery stuff for HttpVerbs.Post
if (String.Compare(filterContext.HttpContext.Request.HttpMethod, "post", true) == 0)
{
var authorize = new AuthorizeAttribute();
authorize.OnAuthorization(filterContext);
if (filterContext.Result != null) // Short circuit validation
return;
var forgery = new ValidateAntiForgeryTokenAttribute();
forgery.OnAuthorization(filterContext);
}
base.OnAuthorization(filterContext);
}
}
Некоторые ссылки на базу кода MVC:
ControllerActionInvoker#InvokeAuthorizationFilters()
строка 283. То же короткое замыкание.
AntiForgeryData#GetUsername()
строка 98. Новая функциональность.