0

J'ai l'application ASP.NET MVC 5 en utilisant .Net 4.5.1. L'application a plusieurs jQuery ajax post méthode que les données POST au serveur. Pour éviter la falsification de requête intersite (XSRF) j'ai ajouté ce qui suit dans _layout.cshtmlValidateAntiForgeryToken ne fonctionne pas asp.net mvc avec ajax post

@Html.AntiForgeryToken() 

et aussi le javascript qui envoie le jeton avec tous les ajax POST HTTPHeader

$(document).ajaxSend(function (event, jqXHR, ajaxOptions) { 
      if (ajaxOptions.type === 'POST') { 
       jqXHR.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val()); 
      }     
     }); 

puis dans le contrôleur méthode d'action Je

[ValidateAntiForgeryToken]   
    [HttpPost] 
    public ActionResult Save(MyModel model) 
    { 
     //save and return json data 
    } 

Cependant ValidateAntiForgeryToken thorwing exception

Le champ de formulaire anti-falsification requis "__RequestVerificationToken" est non présent.

J'ai vérifié que __RequestVerificationToken est ajouté au httpscript pour chaque Ajax POST.

J'ai une autre application qui a été développée en utilisant ASP.NET Core et j'ai la même fonctionnalité là (sauf le nom d'en-tête est RequestVerificationToken au lieu de __RequestVerificationToken) et son travail dans ASP.NET Core.

Pourquoi la même chose ne fonctionne pas dans ASP.NET MVC lorsque le jeton est inclus dans l'en-tête? Y at-il une différence ValidateAntiForgeryToken dans ASP.NET Core vs ASP.NET MVC 5?

+0

double possible de [appels Ajax jQuery et le Html.AntiForgeryToken ()] (http://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken) – VahidN

+0

@VahidN ce n'est pas le même problème. J'ai traversé le lien fourni avant. – LP13

Répondre

1

Pour résoudre votre problème, tout reste identique, à l'exception de setRequestHeader. Passez __RequestVerificationToken dans le corps de demande

data: { 
       __RequestVerificationToken: $('input[name="__RequestVerificationToken"]').val(), 
       // Other properties of data 
      }, 
+0

oui dans asp.net mvc si j'ajoute aux données puis son fonctionnement? Cependant, je suppose que dans le noyau asp.net cela fonctionne que vous ajoutiez dans 'data' ou dans' header'. Pour résoudre mon problème, j'ai implémenté la méthode personnalisée ValidateAntiForgeryTokenAttribute. – LP13

+0

Asp.net core vérifie l'en-tête et le corps à la fois pour le jeton. – Kaushal

0

Pour résoudre mon problème, je l'ai mis en œuvre ValidateAntiForgeryToken de coutume. J'ai décidé d'inclure le jeton dans l'en-tête.

  1. J'ai plusieurs méthodes ajax POST tout au long de l'application, donc au lieu de ajouter sur chaque méthode d'action que je veux valider à l'échelle mondiale.
  2. Du côté client, je veux inclure le jeton implicitement pour chaque requête POST ajax . (Application a également des grilles de kendo qui fait ajax demande de poste pour obtenir des données)
  3. ajax poste data pourrait être objet JSON ou sous forme sérialisé, qui permet d'ajouter __RequestVerificationToken à data peu délicate (pas impossible), surtout quand je veux pour le gérer globalement.

Alors voici mon code complet

Filtre

public class ValidatePostAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter 
    { 
     private const string _tokenKey = "__RequestVerificationToken"; 
     public void OnAuthorization(AuthorizationContext filterContext) 
     { 
      if (filterContext == null) 
      { 
       throw new ArgumentNullException("filterContext"); 
      } 

      if (filterContext.HttpContext.Request.HttpMethod.ToUpper() == "POST") 
      { 
       if (filterContext.HttpContext.Request.IsAjaxRequest()) 
       { 
        if (filterContext.HttpContext.Request.Cookies.Get(_tokenKey) == null || 
        filterContext.HttpContext.Request.Headers.Get(_tokenKey) == null) 
        { 
         throw new HttpPostAntiForgeryException("Invalid Verification Token."); 
        } 

        AntiForgery.Validate(filterContext.HttpContext.Request.Cookies[_tokenKey].Value, filterContext.HttpContext.Request.Headers[_tokenKey]); 
       }     
      } 
     } 
    } 

Exception

public sealed class HttpPostAntiForgeryException : HttpException 
{ 
    public HttpPostAntiForgeryException() 
    { 
    } 
    public HttpPostAntiForgeryException(string message) : base(message) 
    { 
    } 
} 

Ajouter un filtre globalement

public class FilterConfig 
{ 
    public static void RegisterGlobalFilters(GlobalFilterCollection filters) 
    { 
     filters.Add(new HandleErrorAttribute()); 
     filters.Add(new AuthorizeAttribute() { Order = 0 }); 
     filters.Add(new ValidatePostAntiForgeryTokenAttribute() { Order = 1 }); 
    } 
} 

_layout.cshtml - js pour ajouter jeton

$.ajaxPrefilter(function (options, originalOptions, jqXHR) { 
       if (originalOptions.type === "POST") 
        jqXHR.setRequestHeader('__RequestVerificationToken', $('input[name="__RequestVerificationToken"]').val()); 
      }); 

jeton Ajouter dans _layout.cshtml

@Html.AntiForgeryToken()