2012-10-01 65 views
11

En una página Web, se proporciona un hipervínculo (GET) que el usuario puede hacer clic en para autenticar:ASP.NET MVC - ValidateAntiForgeryToken expira

@Html.ActionLink("Please Login", "MyMethod", "MyController") 

Se correlaciona con el siguiente método que devuelve un controlador de Vista:

[RequireHttps] 
    public ActionResult MyMethod() 
    { 
     return this.View(new MyModel()); 
    } 

Esta vista contiene el formulario en el que el usuario proporciona sus credenciales; el Formulario contiene el AntiForgeryToken requerido.

Cuando el usuario envía el formulario, el siguiente método controlador se llama:

[HttpPost] 
    [RequireHttps] 
    [ValidateAntiForgeryToken] 
    public ActionResult MyMethod(MyModel model) 
    { 
     // my logic 
    } 

Esto funciona perfectamente bien, la mayoría de las veces ...

Sin embargo, si el usuario deja su navegador abierto durante un período "significativo" de tiempo y luego realiza los siguientes pasos en rápida sucesión:

  1. hace clic en el hipervínculo (GET) para cargar el formulario de conexión
  2. rellena el formulario y presenta

Consiguen una excepción informándoles de que el token Anti-Falsificación o bien no fue proporcionado o no era válida.

No entiendo por qué este es el caso: la Vista (que contiene el formulario) se crea después de que el navegador estuvo inactivo y por lo tanto los tokens antifalsificación deberían estar todos "frescos". Sin embargo, algo está evidentemente mal con este diseño, pero no estoy seguro de cómo corregirlo.

Gracias de antemano si tiene alguna sugerencia.

Griff

+0

sólo quiero mencionar que mi aplicación ha experimentado este problema desde hace unos años y me gustaría tener una solución. Intenté todas las correcciones de teclas de máquina estándar. – Jonathan

+0

Enrolle esas mangas y sumérjase en la fuente. Yo seré el hombre de la bomba. – Nick

+0

Hay un [artículo] (http://stackoverflow.com/questions/5767768/troubleshooting-anti-forgery-token-problems?rq=1) que detalla los pasos de validación para el token. Un paso es validar en contra del usuario del Contexto, no estoy seguro de si eso podría haberse desviado. De cualquier manera, la solución no está clara. – DrGriff

Respuesta

9

estoy tratando con este mismo problema y si bien entiendo el problema, no estoy seguro todavía de la mejor resolución.

El proceso Anti-ForgeryToken coloca un valor de entrada en el formulario con un segundo valor almacenado en una cookie RequestVerificationToken. Ambos se envían al servidor y si no coinciden, se genera el error.

La cookie RequestVerficationToken tiene un valor de caducidad establecido como Session. Entonces, cuando el usuario deja el navegador abierto en la página durante mucho tiempo y luego lo envía, la marca de tiempo de la cookie se compara con el valor de tiempo de espera de la sesión en el servidor (un valor predeterminado de 20 minutos aproximadamente) y se ha superado. y así la validación del token falla.

Posibles soluciones, todas las cuales tienen problemas potenciales;

  1. Ponga un temporizador de JavaScript en la página y actualice con un valor menos que el tiempo de espera de la sesión.
  2. Capture System.Web.Mvc.HttpAntiForgeryException en el servidor y redireccione a la misma página.
  3. Aumenta tu sesión de tiempo de espera
  4. Cambio de la expiración de la anti-falsificación símbolo
+1

Nota, según tengo entendido, la clave del equipo se usa para validar Anti-ForgeryToken en el servidor y es necesaria para su uso en una webfarm (y establecer una clave de máquina estática podría resolver una condición de error causada por un reinicio del proceso de trabajo en el servidor), sin embargo, no resolverá el problema de caducidad de la cookie. –

+0

Como dijo, la caducidad de las cookies está ligada a la sesión, por lo que la solución 3 también debería dar como resultado la solución 4. A menos que anule manualmente cómo se genera la cookie de alguna manera. Intenté con la solución 1 en el pasado y no siempre es totalmente confiable, por lo que una combinación de 3 (si es posible) y 2 parecen ser las mejores opciones. – Rowan