asp.net-mvc
Html.AntiForgeryToken
Ricerca…
introduzione
Il token anti-contraffazione può essere utilizzato per proteggere la tua applicazione contro la falsificazione di richieste tra siti. Per utilizzare questa funzione, chiamare il metodo AntiForgeryToken da un modulo e aggiungere l'attributo ValidateAntiForgeryTokenAttribute al metodo di azione che si desidera proteggere.
Genera un campo modulo nascosto (token anti-contraffazione) che viene convalidato quando il modulo viene inviato.
Sintassi
- @ Html.AntiForgeryToken ()
Osservazioni
Quando si invia una richiesta __RequestVerificationToken
con token CSRF ( __RequestVerificationToken
) assicurarsi che il tipo di contenuto non sia impostato su application/json
. Se si utilizza jQuery, il tipo di contenuto viene impostato automaticamente su application/x-www-form-urlencoded
che viene quindi riconosciuto da ASP.NET MVC.
Attenzione
Prestare attenzione quando si imposta questo valore. L'utilizzo improprio può aprire vulnerabilità di sicurezza nell'applicazione.
Utilizzo di base
Il metodo helper @Html.AntiForgeryToken()
protegge dagli attacchi di falsificazione delle richieste tra siti (o CSRF).
Può essere utilizzato semplicemente utilizzando l' Html.AntiForgeryToken()
all'interno di uno dei moduli esistenti e decorando l'azione controller corrispondente con l'attributo [ValidateAntiForgeryToken]
.
Razor (YourView.cshtml)
@using (Html.BeginForm("Manage", "Account")) {
@Html.AntiForgeryToken()
<!-- ... -->
}
O
<form>
@Html.AntiForgeryToken()
<!-- ... -->
</form>
Controller (YourController.cs)
Il metodo di azione target:
[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult ActionMethod(ModelObject model)
{
// ...
}
Disabilita controllo euristico identità
Spesso si vedrà un'eccezione
Anti forgery token is meant for user "" but the current user is "username"
Questo perché il token Anti-Forgery è anche collegato all'utente attualmente loggato. Questo errore appare quando un utente effettua l'accesso ma il suo token è ancora collegato a essere un utente anonimo per il sito.
Esistono alcuni modi per risolvere questo problema, ma se preferisci non avere token CSRF collegati allo stato di accesso di un utente, puoi disabilitare questa funzione.
Inserire questa riga nel file Global.asax
o nella logica di avvio dell'applicazione simile.
AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;
Convalida tutti i messaggi
A causa della vulnerabilità causata da CSRF, è generalmente considerata una buona pratica controllare un AntiForgeryToken su tutti gli HttpPost a meno che non ci sia una buona ragione per non farlo (qualche problema tecnico con il post, c'è un altro meccanismo di autenticazione e / o post non muta stato come salvare in un db o in un file). Per assicurarti di non dimenticarti, puoi aggiungere uno speciale GlobalActionFilter che controlla automaticamente tutti gli HttpPost a meno che l'azione non sia decorata con un attributo speciale "ignora".
[AttributeUsage(AttributeTargets.Class)]
public class ValidateAntiForgeryTokenOnAllPosts : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
// Only validate POSTs
if (request.HttpMethod == WebRequestMethods.Http.Post)
{
bool skipCheck = filterContext.ActionDescriptor.IsDefined(typeof(DontCheckForAntiForgeryTokenAttribute), true)
|| filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(DontCheckForAntiForgeryTokenAttribute), true);
if (skipCheck)
return;
// Ajax POSTs and normal form posts have to be treated differently when it comes
// to validating the AntiForgeryToken
if (request.IsAjaxRequest())
{
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
var cookieValue = antiForgeryCookie != null
? antiForgeryCookie.Value
: null;
AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
}
else
{
new ValidateAntiForgeryTokenAttribute()
.OnAuthorization(filterContext);
}
}
}
}
/// <summary>
/// this should ONLY be used on POSTS that DO NOT MUTATE STATE
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public sealed class DontCheckForAntiForgeryTokenAttribute : Attribute { }
Per assicurarti che venga controllato su tutte le richieste, aggiungilo ai tuoi filtri azione globali
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//...
filters.Add(new ValidateAntiForgeryTokenOnAllPosts());
//...
}
}
Utilizzo avanzato: applica il filtro predefinito Antiforgery per ogni POST
Potremmo dimenticarci di applicare l' Antiforgery attribute
per ogni richiesta POST
quindi dovremmo farlo per impostazione predefinita. Questo esempio si assicurerà che il Antiforgery filter
sia sempre applicato a tutte POST
richieste POST
.
Innanzitutto crea il nuovo filtro AntiForgeryTokenFilter
:
//This will add ValidateAntiForgeryToken Attribute to all HttpPost action methods
public class AntiForgeryTokenFilter : IFilterProvider
{
public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor)
{
List<Filter> result = new List<Filter>();
string incomingVerb = controllerContext.HttpContext.Request.HttpMethod;
if (String.Equals(incomingVerb, "POST", StringComparison.OrdinalIgnoreCase))
{
result.Add(new Filter(new ValidateAntiForgeryTokenAttribute(), FilterScope.Global, null));
}
return result;
}
}
Quindi registra questo filtro personalizzato su MVC, Application_Start:
public class FilterConfig
{
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
//Cactch generic error
filters.Add(new HandleErrorAttribute());
//Anti forgery token hack for every post request
FilterProviders.Providers.Add(new AntiForgeryTokenFilter());
}
}
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
Quindi ora tutte le tue richieste POST
sono protette per impostazione predefinita utilizzando gli attributi Antiforgery, quindi non è più necessario avere attributo [ValidateAntiForgeryToken]
su ciascun metodo POST.
Utilizzo di AntiForgeryToken con Jquery Ajax Request
Innanzitutto, crea il modulo
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
}
Metodo di azione
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test(FormViewModel formData)
{
// ...
}
copione
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
var formData = new FormData($('form')[0]);
$.ajax({
method: "POST",
url: "/demo/test",
data: formData ,
success: function (data) {
console.log(data);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(errorThrown);
}
})
</script>
Assicurati che contentType non sia impostato su qualcosa oltre a application/x-www-form-urlencoded
e se il suo jquery non specificato è impostato su application/x-www-form-urlencoded