asp.net-mvc
Html.AntiForgeryToken
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