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



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow