如果你使用RC2忽略了所有过滤器代码,那么你需要做的就是
StartUp.cs
services.AddAntiforgery(options => options.HeaderName = "YOUR_HEADER_NAME");
适用于RC1
之前我使用IAuthorization过滤器来验证AntiForgery令牌,但似乎MVC6中的事情发生了巨大变化。我找不到任何描述过滤更改的文档。
这是我的旧代码
[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 ..}
由于
答案 0 :(得分:1)
以下是基于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);
}
}
}
装饰你的控制器/动作
[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/
}
并在您的AJAX调用中,将从@ Html.AntiForgeryToken()生成的令牌放入请求标头中。
$.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()
},