2012-03-26 4 views
6

У нас есть конкретная проблема с токеном анти-подделки на странице входа. Если пользователь входит в систему только с одним активным окном, все работает отлично, если пользователь открывает страницу входа в два разных окна и регистрируется в окне A (никаких проблем не будет входить в систему), и возвращается к логину из окна B в этом окне пользователь получит «Необходимый токен анти-подделки не был поставлен или был недействителен».Значок многоточия Mvc3 Antiforgery

Есть ли способ обойти этот другой, чтобы удалить токен анти-подделки из действия вида/контроллера? Мы предпочли бы иметь токен для дополнительной безопасности!

Это очень похоже на этот вопрос, однако это было запрошено MVC2 MVC ValidateAntiForgeryToken multi-tabs problem

+0

Я оставил вам еще один ответ - я ответил на свой вопрос! –

ответ

20

Такое поведение в MVC3 или MVC4 является таким же разработанным, однако оно очень недружелюбен пользователю, как описано выше, однако в производстве эта проблема должна быть решена изящно, и приложение должно справиться с этой странной ситуацией. Решение этой проблемы заключается в создании фильтра, который применяется к сообщению входа, который проверяет, был ли пользователь зарегистрирован и отобрал их на правильной странице, иначе они останутся на странице входа.

Ниже приведен код для фильтра атрибутов

/// <summary> 
/// Handle Antiforgery token exception and redirect to customer area if the user is Authenticated 
/// </summary> 
public class RedirectOnError : HandleErrorAttribute 
{ 
    /// <summary> 
    /// Override the on exception method and check if the user is authenticated and redirect the user 
    /// to the customer service index otherwise continue with the base implamentation 
    /// </summary> 
    /// <param name="filterContext">Current Exception Context of the request</param> 
    public override void OnException(ExceptionContext filterContext) 
    { 
     if (filterContext.Exception is HttpAntiForgeryException && filterContext.HttpContext.User.Identity.IsAuthenticated) 
     { 
      // Set response code back to normal 
      filterContext.HttpContext.Response.StatusCode = 200; 

      // Handle the exception 
      filterContext.ExceptionHandled = true; 

      UrlHelper urlH = new UrlHelper(filterContext.HttpContext.Request.RequestContext); 

      // Create a new request context 
      RequestContext rc = new RequestContext(filterContext.HttpContext, filterContext.RouteData); 

      // Create a new return url 
      string url = RouteTable.Routes.GetVirtualPath(rc, new RouteValueDictionary(new { Controller = "CustomerArea", action = "Index" })).VirtualPath; 

      // Check if there is a request url 
      if (filterContext.HttpContext.Request.Params["ReturnUrl"] != null && urlH.IsLocalUrl(filterContext.HttpContext.Request.Params["ReturnUrl"])) 
      { 
       url = filterContext.HttpContext.Request.Params["ReturnUrl"]; 
      } 

      // Redirect the user back to the customer service index page 
      filterContext.HttpContext.Response.Redirect(url, true); 
     } 
     else 
     { 
      // Continue to the base 
      base.OnException(filterContext); 
     } 
    } 
} 

Это пример использования

 [HttpPost] 
     **[RedirectOnError]** 
     [ValidateAntiForgeryToken] 
     public ActionResult LogOn(LogOnViewModel model, UserSessionState session, string returnUrl) 
     { 
     ..... 
     } 
+0

Я не понимаю, что произойдет, если пользователь не зашел в систему ... потому что оставшееся на странице регистрации может привести к повторению исключения. – ilans

+2

В ответ на IlanS - код если (filterContext.Exception является HttpAntiForgeryException && filterContext.HttpContext.User.Identity.IsAuthenticated) будет применяться только редирект, если пользователь вошел в систему, иначе регулярное исключение для аутентифицированного пользователя, не является выброшены. – MORCHARD

+0

Отличное решение! –

4

После того, как вы войти, все предыдущие маркеры являются недействительными. Вот как это должно работать. Naz получает близко к правильному ответу, за исключением того, что токен в cookie не сохраняет имя пользователя. Только токен в форме. Именно из-за этой проблемы: если пользователь входит в систему, все существующие маркеры должны быть признаны недействительными, но недействительность самого файла cookie будет слишком проблематичной и недружественной для пользователя.

Смежные вопросы