Sök…


Introduktion

Anti-forgery-tokenet kan användas för att skydda din ansökan mot förfalskning på olika platser. För att använda den här funktionen, anropa AntiForgeryToken-metoden från ett formulär och lägg till ValidateAntiForgeryTokenAttribute-attributet till åtgärdsmetoden som du vill skydda.

Genererar ett doldt formulärfält (anti-forgery token) som valideras när formuläret skickas in.

Syntax

  • @ Html.AntiForgeryToken ()

Anmärkningar

När du skickar in en ajaxbegäran med CSRF-token ( __RequestVerificationToken ), se till att innehållstypen inte är inställd på application/json . Om du använder jQuery ställer den automatiskt in innehållstypen till application/x-www-form-urlencoded som sedan identifieras av ASP.NET MVC.

Varning

Var försiktig när du ställer in detta värde. Att använda det felaktigt kan öppna säkerhetsproblem i applikationen.

Grundläggande användning

Den @Html.AntiForgeryToken() hjälpare metod skyddar mot cross-site begäran förfalskning (eller CSRF) attacker.

Det kan användas genom att helt enkelt använda Html.AntiForgeryToken() -hjälpen i en av dina befintliga former och dekorera dess motsvarande Controller Action med attributet [ValidateAntiForgeryToken] .

Razor (YourView.cshtml)

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

ELLER

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

Controller (YourController.cs)

Målåtgärdsmetoden:

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

Inaktivera identitetsheuristisk kontroll

Ofta ser du ett undantag

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

Detta beror på att Anti-Forgery-tokenet också är länkat till den nuvarande inloggade användaren. Det här felet visas när en användare loggar in men deras token är fortfarande kopplad till att vara en anonym användare för webbplatsen.

Det finns några sätt att fixa detta beteende, men om du hellre inte vill ha CSRF-token länkade till ett användares inloggade tillstånd kan du inaktivera den här funktionen.

Lägg denna rad i din Global.asax fil eller liknande applikationsstartlogik.

AntiForgeryConfig.SuppressIdentityHeuristicChecks = true;

Validera alla inlägg

På grund av sårbarheten orsakad av CSRF anses det vanligtvis vara en bra praxis att kontrollera om det finns en AntiForgeryToken på alla HttpPosts såvida det inte finns en god anledning att inte göra det (något tekniskt problem med inlägget, det finns en annan autentiseringsmekanism och / eller inlägget muterar inte tillstånd som att spara till en db eller fil). För att säkerställa att du inte glömmer kan du lägga till ett speciell GlobalActionFilter som automatiskt kontrollerar alla HttpPosts såvida inte åtgärden är dekorerad med ett speciellt "ignorera" -attribut.

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

För att se till att det kontrolleras på alla förfrågningar, lägg bara till det i dina Global Action Filters

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

Avancerad användning: Använd standard Antiforgery-filter för varje POST

Vi kan glömma att tillämpa Antiforgery attribute för varje POST begäran så vi ska göra det som standard. Detta prov säkerställer att Antiforgery filter alltid tillämpas på varje POST begäran.

AntiForgeryTokenFilter nytt 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;
    }
}

Registrera sedan detta anpassade filter till 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);
    }
}

Så nu är alla dina POST förfrågningar som standard skyddade med Antiforgery-attribut så vi behöver inte längre ha [ValidateAntiForgeryToken] -attribut på varje POST-metod.

Använda AntiForgeryToken med Jquery Ajax Begäran

Först skapar du formuläret

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

Åtgärdsmetod

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

Manus

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

Se till att contentType inte är inställt på något annat än application/x-www-form-urlencoded och om dess inte angivna Jquery är standardvärden för application/x-www-form-urlencoded



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow