Zoeken…


Invoering

Het anti-vervalsingstoken kan worden gebruikt om uw toepassing te beschermen tegen vervalsing van cross-site-aanvragen. Als u deze functie wilt gebruiken, roept u de AntiForgeryToken-methode aan vanuit een formulier en voegt u het kenmerk ValidateAntiForgeryTokenAttribute toe aan de actiemethode die u wilt beschermen.

Genereert een verborgen formulierveld (anti-vervalsingstoken) dat wordt gevalideerd wanneer het formulier wordt verzonden.

Syntaxis

  • @ Html.AntiForgeryToken ()

Opmerkingen

Let er bij het indienen van een ajax-verzoek met CSRF-token ( __RequestVerificationToken ) op dat het inhoudstype niet is ingesteld op application/json . Als u jQuery gebruikt, wordt het inhoudstype automatisch ingesteld op application/x-www-form-urlencoded die vervolgens wordt herkend door ASP.NET MVC.

Voorzichtigheid

Wees voorzichtig bij het instellen van deze waarde. Onjuist gebruik kan beveiligingsproblemen in de toepassing veroorzaken.

Basis gebruik

De @Html.AntiForgeryToken() beschermt tegen aanvallen op verschillende sites (CSRF).

Het kan worden gebruikt door eenvoudig de helper Html.AntiForgeryToken() in een van uw bestaande formulieren en de bijbehorende controlleractie te decoreren met het kenmerk [ValidateAntiForgeryToken] .

Scheermes (YourView.cshtml)

@using (Html.BeginForm("Manage", "Account")) {
    @Html.AntiForgeryToken()  
    <!-- ... -->
}

OF

<form>
    @Html.AntiForgeryToken()
    <!-- ... -->
</form>

Controller (YourController.cs)

De doel actiemethode:

[ValidateAntiForgeryToken]
[HttpPost]
public ActionResult ActionMethod(ModelObject model)
{
    // ...
}

Identiteitsheuristische controle uitschakelen

Vaak zie je een uitzondering

Anti forgery token is meant for user "" but the current user is "username"

Dit komt omdat het anti-vervalsingstoken ook is gekoppeld aan de huidige aangemelde gebruiker. Deze fout verschijnt wanneer een gebruiker inlogt, maar zijn token is nog steeds gekoppeld aan een anonieme gebruiker voor de site.

Er zijn een paar manieren om dit probleem te verhelpen, maar als u liever geen CSRF-tokens hebt die zijn gekoppeld aan de ingelogde status van een gebruiker, kunt u deze functie uitschakelen.

Plaats deze regel in uw Global.asax bestand of vergelijkbare opstartlogica van de toepassing.

AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;

Alle berichten valideren

Vanwege de kwetsbaarheid veroorzaakt door CSRF, wordt het over het algemeen als een goede praktijk beschouwd om op alle HttpPosts te controleren op een AntiForgeryToken, tenzij er een goede reden is om het niet te doen (een technisch probleem met de post, er is een ander authenticatiemechanisme en / of de bericht verandert de status niet zoals opslaan in een DB of bestand). Om ervoor te zorgen dat u het niet vergeet, kunt u een speciaal GlobalActionFilter toevoegen dat automatisch alle HttpPosts controleert, tenzij de actie is versierd met een speciaal kenmerk "negeren".

[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 { }

Om ervoor te zorgen dat alle aanvragen worden aangevinkt, voegt u het gewoon toe aan uw Global Action-filters

public class FilterConfig
{
    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //...
        filters.Add(new ValidateAntiForgeryTokenOnAllPosts());
        //...
    }
}

Vooraf gebruik: Pas standaard Antiforgery-filter toe voor elke POST

We kunnen vergeten het Antiforgery attribute te passen voor elk POST verzoek, dus we moeten het standaard maken. Dit voorbeeld zorgt ervoor dat het Antiforgery filter altijd op elk POST verzoek wordt toegepast.

Maak eerst een nieuw AntiForgeryTokenFilter filter:

//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;
    }
}

Registreer dit aangepaste filter vervolgens bij 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);
    }
}

Dus nu worden al uw POST aanvragen standaard beschermd met behulp van antiforgery-kenmerken, zodat we niet langer [ValidateAntiForgeryToken] -kenmerk op elke POST-methode moeten hebben.

Gebruik van AntiForgeryToken met Jquery Ajax Request

Maak eerst het formulier

@using (Html.BeginForm())
{
  @Html.AntiForgeryToken()
}

Actie methode

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test(FormViewModel formData)
{
    // ...
}

Script

<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>

Zorg ervoor dat contentType op niets anders staat dan application/x-www-form-urlencoded en als het niet is opgegeven Jquery standaard op application/x-www-form-urlencoded



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow