2012-03-26 12 views
6

Mamy konkretny problem z tokenem przeciw fałszerstwu na stronie logowania. Jeśli użytkownik loguje się tylko jednym aktywnym oknem, wszystko działa świetnie, jednak jeśli użytkownik otworzy stronę logowania w dwóch różnych oknach i zaloguje się z okna A (żadne problemy nie będą się logować), a następnie wraca do logowania z okna B w tym oknie użytkownik otrzyma "Żeton wymaganego zabezpieczenia przed fałszowaniem nie został dostarczony lub był nieważny".Mvc3 Token Antiforgery multi tabs

Czy jest jakiś sposób obejścia tego drugiego, aby usunąć token przeciwdziałający fałszerstwu z działania widoku/kontrolera? Wolelibyśmy mieć token dla dodatkowego bezpieczeństwa!

ta jest bardzo podobna do tej kwestii jednak ten został poproszony o mvc2 MVC ValidateAntiForgeryToken multi-tabs problem

+0

zostawiłem jeszcze jedną odpowiedź - mam odpowiedziałeś na moje własne pytanie! –

Odpowiedz

20

To zachowanie w MVC3 lub MVC4 zostało zaprojektowane, ale jest bardzo nieprzyjazne dla użytkownika, jak wyjaśniono powyżej, jednak w produkcji ten problem musi być rozwiązany z wdziękiem, a aplikacja musi poradzić sobie w tej dziwnej sytuacji. Rozwiązaniem tego problemu jest utworzenie filtru, który zostanie zastosowany do wpisu logowania, który sprawdzi, czy użytkownik jest zalogowany i przeniesie go na właściwą stronę, w przeciwnym razie pozostaną na stronie logowania.

Poniżej znajduje się kod dla filtra atrybutu

/// <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); 
     } 
    } 
} 

Jest to przykład wykorzystania

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

Nie rozumiem, co się stanie, jeśli użytkownik nie jest zalogowany ... ponieważ pozostanie na stronie rejestrowania może ponownie spowodować wyjątek. – ilans

+2

W odpowiedzi na kod IlanS - kod , jeśli (filterContext.Exception jest HttpAntiForgeryException && filterContext.HttpContext.User.Identity.IsAuthenticated) zastosuje przekierowanie tylko, jeśli użytkownik jest zalogowany, w przeciwnym razie zwykły wyjątek dla nieuwierzytelnionego użytkownika jest rzucony. – MORCHARD

+0

Świetne rozwiązanie! –

4

Po zalogowaniu wszystkie poprzednie tokeny są nieważne. Tak to powinno działać. Naz zbliża się do właściwej odpowiedzi, z wyjątkiem tego, że token w ciasteczku nie przechowuje nazwy użytkownika. Działa tylko token w formularzu. Właśnie z powodu tego problemu: jeśli użytkownik się zaloguje, wszystkie istniejące tokeny z postaci powinny zostać unieważnione, ale unieważnienie samego pliku cookie będzie zbyt problematyczne i nieprzyjazne dla użytkownika.