如何在ASP.NET Core 3.1中实现自定义ValidateAntiforgeryTokenAuthorizationFilter [英] How to implement custom ValidateAntiforgeryTokenAuthorizationFilter in ASP.NET Core 3.1
问题描述
我要实现在使用身份验证令牌身份验证(Bearer
)时跳过防伪令牌验证的过滤。
在ASP.NET Core 2.2中,ValidateAntiforgeryTokenAuthorizationFilter
和AutoValidateAntiforgeryTokenAuthorizationFilter
是公共的(即使位于Microsoft.AspNetCore.Mvc.ViewFeatures.Internal
命名空间中),因此我只能从后者继承并轻松重写ShouldValidate
方法。
在ASP.NET Core 3.0中,它们成为内部的,因此不可能仅仅从它们继承。我可以直接复制粘贴代码,但这显然不是理想的解决方案。
我在关注MSDN的Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core文章,但它实际上没有提到任何与我的方案相关的内容。
csrf
通常,如果您可以在编译时确定应该忽略推荐答案标记,则可以使用[IgnoreAntiforgeryToken]
属性。如果您在运行时需要这种功能,可以创建一个自定义FilterProvider
,如果有Authroization: Bearer json-web-token
头,将提供IAntiforgeryPolicy
。
例如,我们可以创建一个自定义的AutoSkipAntiforgeryFilterProvider
,如下所示:
public class AutoSkipAntiforgeryFilterProvider: IFilterProvider
{
private const string BEARER_STRING = "Bearer";
public int Order => 999;
public void OnProvidersExecuted(FilterProviderContext context) { }
public void OnProvidersExecuting(FilterProviderContext context)
{
if (context == null) { throw new ArgumentNullException(nameof(context)); }
if (context.ActionContext.ActionDescriptor.FilterDescriptors != null)
{
var headers = context.ActionContext.HttpContext.Request.Headers;
if (headers.ContainsKey("Authorization"))
{
var header = headers["Authorization"].FirstOrDefault();
if(header.StartsWith(BEARER_STRING,StringComparison.OrdinalIgnoreCase))
{
var FilterDescriptor = new FilterDescriptor(SkipAntiforgeryPolicy.Instance, FilterScope.Last);
var filterItem = new FilterItem( FilterDescriptor,SkipAntiforgeryPolicy.Instance);
context.Results.Add(filterItem);
}
}
}
}
// a dummy IAntiforgeryPolicy
class SkipAntiforgeryPolicy : IAntiforgeryPolicy, IAsyncAuthorizationFilter
{
// a singleton
public static SkipAntiforgeryPolicy Instance = new SkipAntiforgeryPolicy();
public Task OnAuthorizationAsync(AuthorizationFilterContext context) => Task.CompletedTask;
}
}
并在启动中注册此过滤提供程序:
services.TryAddEnumerable( ServiceDescriptor.Singleton<IFilterProvider, AutoSkipAntiforgeryFilterProvider>());
现在,即使有[ValidateAntiForgeryToken]
属性,它也会绕过AntiForgery
。
[演示]
假设我们有一个用[ValidateAntiForgeryToken]
注释的操作方法:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name")] XModel xModel)
{
....
}
正常情况下,会使用CSRF令牌保护此方法。但是如果您发送如下请求:
POST /XModels/Create HTTP/1.1 Authorization: Bearer Xyz Content-Type: application/x-www-form-urlencoded ...
它不会验证CSRF令牌。
这篇关于如何在ASP.NET Core 3.1中实现自定义ValidateAntiforgeryTokenAuthorizationFilter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!