2016-05-17 14 views
0

Wenn Ihr mit RC2 den gesamten Code-Filter ignorieren alles, was SieWie Fälschungs Token in Ajax-Header mit IAuthorizationFilter in MVC6 RC1 RC2 validieren

StartUp.cs

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

ist tun müssen, um für RC1

Früher habe ich einen IAuthorization-Filter verwendet, um AntiForgery-Tokens zu validieren, aber es sieht so aus, als hätten sich die Dinge in MVC6 drastisch geändert. Ich kann keine Dokumentation finden, die die Filteränderungen beschreibt.

Das ist mein alter 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 ..} 
  • Was ist der empfohlene Weg, die gleiche Sache in MVC6 zu erreichen?
  • Kann mir jemand auf die Dokumentation verweisen?

Dank

+0

[MVC Kernfilter Dokumentation] (https://docs.asp.net/en/latest/mvc/controllers/filters.html). Nicht sicher, was für eine Antwort Sie brauchen, scheint es ziemlich einfach (nicht zu erwähnen, nicht anders als MVC 5). – NightOwl888

+0

Danke..Ich habe diese Dokumentation total vermisst – PingCrosby

Antwort

1

Hier ist eine Beispielimplementierung auf der Dokumentations-MVC basiert.

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

Ihre controller/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/ 
    } 

dekorieren und in der AJAX-Aufruf, legen Sie die Token generiert von @ Html.AntiForgeryToken() in die Request-Header.

$.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() 
},