2016-05-17 2 views
0

si vous utilisez RC2 ignorer tout le code du filtre tout ce que vous devez faire estComment valider l'en-tête jeton anti-contrefaçon Ajax en utilisant IAuthorizationFilter dans MVC6 RC1 RC2

StartUp.cs

services.AddAntiforgery(options => options.HeaderName = "YOUR_HEADER_NAME"); 

Pour RC1

Auparavant, j'ai utilisé un filtre IAuthorization pour valider les jetons AntiForgery, mais il semble que les choses aient radicalement changé dans MVC6. Je ne trouve aucune documentation décrivant les changements de filtrage.

Ceci est mon ancien code

[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 
public sealed class CustomValidateAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter 
{ 
    // why is this necessary.. 
    // take a look here http://www.asp.net/web-api/overview/security/preventing-cross-site-request-forgery-%28csrf%29-attacks 
    // the CSRF token is inserted into the AJAX header 
    // 
    public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation) 
    { 
     if (actionContext == null) 
     { 
      throw new ArgumentNullException("actionContext"); 
     } 
     if (continuation == null) 
     { 
      throw new ArgumentNullException("continuation"); 
     } 

     try 
     { 
      // insanely easy -- just extart the cookie token and the headertoken - it they are null who cares the validation will fail 
      var headerToken = actionContext.Request.Headers.GetValues("__RequestVerificationToken").FirstOrDefault(); // ajax headers 
      var cookieToken = actionContext.Request.Headers.GetCookies().Select(s => s[AntiForgeryConfig.CookieName]).FirstOrDefault(); 

      AntiForgery.Validate(cookieToken.Value, headerToken); 
     } 
     catch (HttpAntiForgeryException) 
     { 
      actionContext.Response = new HttpResponseMessage 
      { 
       StatusCode = HttpStatusCode.Forbidden, 
       RequestMessage = actionContext.ControllerContext.Request 
      }; 
      return FromResult(actionContext.Response); 
     } 
     return continuation(); 
    } 

    private Task<HttpResponseMessage> FromResult(HttpResponseMessage result) 
    { 
     var source = new TaskCompletionSource<HttpResponseMessage>(); 
     source.SetResult(result); 
     return source.Task; 
    } 
} 

[Authorize] 
public class SubmissionController : ApiController 
{ 
    [CustomValidateAntiForgeryToken] // note this is a custom filter, named to clarify its not the built in one as thats for views! 
    public HttpResponseMessage Delete(int? ID) {.. blah ..} 
  • Quelle est la méthode recommandée pour obtenir la même chose en MVC6?
  • Quelqu'un peut-il me diriger vers la documentation?

Merci

+0

[MVC Filtre en Documentation] (https://docs.asp.net/en/latest/mvc/controllers/filters.html). Je ne sais pas ce que plus d'une réponse dont vous avez besoin, il semble assez simple (pour ne pas mentionner, pas si différent de MVC 5). – NightOwl888

+0

Merci .. J'ai vraiment raté cette documentation – PingCrosby

Répondre

1

Voici un exemple d'implémentation basée sur la documentation MVC.

public class ValidateAntiForgeryHeaderToken : TypeFilterAttribute 
{ 
    public ValidateAntiForgeryHeaderToken() : base(typeof(ValidateAntiForgeryHeaderTokenImpl)) 
    { 
    } 

    // see https://docs.asp.net/en/latest/mvc/controllers/filters.html 
    // 
    // If you have a simple filter that doesn’t require any arguments, but which has constructor dependencies that need to be filled by DI, 
    // you can inherit from TypeFilterAttribute, allowing you to use your own named attribute on classes and methods (instead of [TypeFilter(typeof(FilterType))]). 
    // 

    private class ValidateAntiForgeryHeaderTokenImpl : IAsyncAuthorizationFilter 
    { 
     private readonly IAntiforgery _antiforgery; 

     public readonly string verificationToken = "X-VerificationToken"; 
     public readonly string antiforgeryCookieName; 

     public ValidateAntiForgeryHeaderTokenImpl(IAntiforgery antiforgery, IOptions<AntiforgeryOptions> antiforgeryOptions) 
     { 
      _antiforgery = antiforgery; 
      antiforgeryCookieName = antiforgeryOptions.Value.CookieName; // if not specified this is autogenerated by mvc 
     } 

     public Task OnAuthorizationAsync(AuthorizationContext context) 
     { 
      string headerToken = context.HttpContext.Request.Headers[verificationToken]; 
      if (headerToken != null) 
      {      
       string antiForgeryCookieValue = context.HttpContext.Request.Cookies[antiforgeryCookieName]; 
       _antiforgery.ValidateTokens(context.HttpContext, new AntiforgeryTokenSet(headerToken, antiForgeryCookieValue)); // throws on invalid 
       return Task.FromResult<object>(null); 
      } 
      return _antiforgery.ValidateRequestAsync(context.HttpContext);    
     } 
    } 
} 

décorez votre contrôleur/action

[HttpPost] 
    [ValidateAntiForgeryHeaderToken] 
    public IActionResult Add([FromBody] someObject data) 
    { 
     // Why Frombody?? https://lbadri.wordpress.com/2014/11/23/web-api-model-binding-in-asp-net-mvc-6-asp-net-5/ 
    } 

et dans votre appel AJAX, placez le jeton généré par @ Html.AntiForgeryToken() dans l'en-tête de demande.

$.ajax({ 
type: 'POST', 
url: '@Url.Action("yourAction", "yourController", new { Area = "yourArea" })', 
dataType: "json", 
contentType: "application/json", 
data: JSON.stringify(data), 
headers: { 
    'X-VerificationToken': $("[name='__RequestVerificationToken']").val() 
},