2012-10-09 16 views
10

Cuando estoy poniendo siguiente código:sistema anti falsificación de ASP.Net MVC

@using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) 
    { 
     @Html.AntiForgeryToken() 
     <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a> 
    } 

la parte

@Html.AntiForgeryToken() 

es thrownig siguiente excepción:

La identidad provisto de tipo 'System.Web.Security.FormsIdentity' está marcado IsAuthenticated = true pero no tiene un valor para Name. De forma predeterminada, el sistema antifalsificación requiere que todas las identidades autenticadas tengan un Nombre único. Si no es posible proporcionar un Nombre único para esta identidad, considere establecer la propiedad estática AntiForgeryConfig.AdditionalDataProvider en una instancia de un tipo que pueda proporcionar alguna forma de identificador único para el usuario actual.

He comprobado muchos ejemplos y he intentado buscar en la web, pero no puedo encontrar ninguna explicación. Me gustaría saber por qué me pasa este error? Y cómo resolverlo para usar antiforgery.

Respuesta

6

Le está diciendo que no funcionará porque, a pesar de haber iniciado sesión, Membership.GetUser().UserName no proporciona un nombre que pueda usarse para hash.

Así que su verdadero problema es, "¿Cómo es que mi conectado usuario no tiene un nombre de usuario?"

+2

Mi verdadero problema es "¿Cómo es que mi usuario ha iniciado sesión a pesar de que acabo de comenzar a depurar por primera vez?" – Ortund

6

Puede haber algunos casos en los que el usuario que inició sesión no tenga establecido Identity.Name (en mi caso, tengo que integrar mi aplicación con algún loco sistema de inicio de sesión). Luego hay dos maneras en torno a:

1) no segura - todos los usuarios serán tratados de la misma manera por antiforgery sistema, independientemente de su estado de autenticación

// System.Web.WebPages.dll 
using System.Web.Helpers; 

// not a production solution 
public class MvcApplication : HttpApplication { 
    protected void Application_Start() { 
    AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; 
    } 
} 

2) seguro - proporcionar su propio camino (personalizado) cómo a distinguir sus usuarios

using System; 
using System.Globalization; 
using System.Web; 
using System.Web.Helpers; 

public class ContoscoAntiForgeryAdditionalDataProvider : IAntiForgeryAdditionalDataProvider { 
    public string GetAdditionalData(HttpContextBase context) { 
    if (context == null) { 
     throw new ArgumentNullException("context"); 
    } 

    var contoscoContext = new ContoscoHttpContext(context); 
    int userID = contoscoContext.GetUserID().GetValueOrDefault(); 
    return Convert.ToString(userID, CultureInfo.InvariantCulture); 
    } 

    public bool ValidateAdditionalData(HttpContextBase context, string additionalData) { 
    string data = GetAdditionalData(context); 
    return string.Compare(data, additionalData, StringComparison.Ordinal) == 0; 
    } 
} 


public class MvcApplication : HttpApplication { 
    protected void Application_Start() { 
    AntiForgeryConfig.AdditionalDataProvider = 
     new ContoscoAntiForgeryAdditionalDataProvider(); 
    } 
} 

donde ContoscoHttpContext es la clase que devuelve identificación de usuario (o cualquier token de usuario único) basada en el contexto actual (es decir HttpContextBase):

public class ContoscoHttpContext { 
    private HttpContextBase _context; 
    public ContoscoHttpContext(HttpContextBase context) { 
    _context = context; 
    } 
    public int? GetUserID() { 
    // TODO: provide your own implementation how to get user id 
    // based on HttpContextBase stored in _context 
    // in my case it was something like 
    // return ((ContoscoPrincipal)_context.User).UserID; 
    } 
} 
+0

Es AntiForgeryConfig.SuppressIdentityHeuristicChecks (con "s"). – sprinter252

+0

@ sprinter252 - buena llamada, arreglada. –

+0

¿Qué hace ContoscoHttpContext? – slolife

Cuestiones relacionadas