ASP.NET MVC AntiForgeryToken mecanismo se basa en el actual HttpContext.User
. Utiliza ese valor para construir el token cuando llamas al Html.AntiForgeryToken()
. Básicamente está bien (ver una explicación en el last paragraph here), pero surge un problema cuando inicias sesión a través de una llamada Ajax .MVC3 AntiForgeryToken se rompe en Ajax login
En mi código, cuando un usuario inicia una sesión, las credenciales se envían como un objeto JSON en Ajax (el valor del campo oculto AntiForgeryToken
también se envía dentro del JSON), el servidor autentica al usuario, se aplica FormsAuthentication.SetAuthCookie() y devuelve un resultado Json que contiene algunos datos específicos del usuario. De esa manera, puedo evitar la actualización completa de la página al iniciar sesión.
El problema es que cada solicitud subsiguiente de Ajax al servidor ahora falla al ValidateAntiForgeryTokenAttribute
, porque ahora espera un token antifalsificación que no es compatible con la cookie antifalsificación.
¿Cómo puedo obtener un token antifalsificación válido para poner en el campo oculto del cliente para que todas las solicitudes Json después de iniciar sesión tengan éxito?
He intentado conseguir un nuevo campo oculto símbolo manualmente (usando AntiForgery.GetHtml()
en la acción, la extracción de la cadena de símbolo en sí, devolviéndolo al cliente en JSON y colocándolo en el campo oculto anti-falsificación manualmente en JavaScript) pero no funciona - una llamada posterior de Ajax falla en el ValidateAntiForgeryTokenAttribute
en el servidor. De hecho, cada llamada a AntiForgery.GetHtml()
(que es esencialmente lo que hace la ayudante Html.AntiForgeryToken()
) produce un token diferente, lo que invalida el anterior.
También traté de establecer HttpContext.User = new GenericPrincipal(new GenericIdentity(email), null);
como se detalla here, pero no funciona.
Nota:This solution no funciona para mí, debido a mi situación específica: Un Ajax de inicio de sesión que cambia la identidad del usuario en el servidor y, por tanto, cada token que se generó antes del inicio de sesión no es válido; this solution tampoco se aplica porque aborda un problema diferente.
¿Por qué está utilizando un AntiForgeryToken en su página de inicio de sesión, cuando el usuario no está autenticado? ¿Qué estás protegiendo? –
La función de inicio de sesión no es una página, es un fragmento dentro de la plantilla del sitio. De hecho, no es necesario en la función de inicio de sesión, pero el problema surge después: después del método de inicio de sesión en el lado del servidor establece el usuario actual (HttpContext.User) y lo devuelve. En esta etapa, la página ya debe tener algún campo oculto de token anti falsificación para atender más llamadas Ajax. –
Phil Haack publicó este artículo hace unos días. ¿Esto de alguna manera está relacionado con tu problema? http://haacked.com/archive/2011/10/10/preventing-csrf-with-ajax.aspx ... "El problema radica en el hecho de que debajo del capó, en lo profundo de la pila de llamadas, el atributo se asoma en la colección Request.Form para tomar el token anti falsificación, pero cuando publica datos codificados en JSON, no hay una colección de formularios para hablar ". – JasperLamarCrabb