asp.net-core - 如何在 ASP.NET Core 3.1 中实现自定义 ValidateAntiforgeryTokenAuthorizationFilter

标签 asp.net-core csrf asp.net-core-webapi antiforgerytoken

我想实现一个过滤器,在使用身份验证 token 身份验证( Bearer )时跳过防伪 token 的验证。

在 ASP.NET Core 2.2 中 ValidateAntiforgeryTokenAuthorizationFilter AutoValidateAntiforgeryTokenAuthorizationFilter 是公共(public)的(即使生活在 Microsoft.AspNetCore.Mvc.ViewFeatures.Internal 命名空间中),所以我能够从后者继承并覆盖 ShouldValidate方法很容易。

在 ASP.NET Core 3.0 中,它们变成了内部的,因此不能仅从它们继承。我可以复制粘贴代码,但这显然不是理想的解决方案。

我在关注 Prevent Cross-Site Request Forgery (XSRF/CSRF) attacks in ASP.NET Core来自 MSDN 的文章,但它并没有真正提到与我的场景相关的任何内容。

最佳答案

通常你可以使用 [IgnoreAntiforgeryToken]属性,如果您可以在编译时确定应该忽略 csrf token 。如果你想在运行时拥有这样的能力,你可以创建一个自定义 FilterProvider 那将提供 IAntiforgeryPolicy 如果有 Authroization: Bearer json-web-token标题。

例如,我们可以创建一个自定义 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;
    }
}

并在 Startup 中注册此过滤器提供程序:
services.TryAddEnumerable( ServiceDescriptor.Singleton<IFilterProvider, AutoSkipAntiforgeryFilterProvider>());

现在它将绕过 AntiForgery即使有 [ValidateAntiForgeryToken]属性。

[演示]

假设我们有一个用 [ValidateAntiForgeryToken] 注释的 Action 方法。 :
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name")] XModel xModel)
{
    ....
}

通常,它将使用 CSRF token 保护此方法。但是,如果您发送如下请求:

POST/XModels/创建 HTTP/1.1
授权:承载Xyz
内容类型:application/x-www-form-urlencoded

...

它不会验证 csrf token 。

关于asp.net-core - 如何在 ASP.NET Core 3.1 中实现自定义 ValidateAntiforgeryTokenAuthorizationFilter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59546096/

相关文章:

jQuery 在 ASP.NET Core 2.2 Razor View 中不可用

c# - 如何获取我在 Asp.Net 核心的 Startup.ConfigureServices 中添加的所有授权策略?

angularjs - 请求中的请求头和 cookie 中的 CSRF token 不匹配

c# - 将 FileContentResult 与未经授权的结果一起使用

c# - ASP.Net Core Content-Disposition 附件/内联

asp.net-core - 替代 HttpResponse.ContentEncoding ASP.NET 5

node.js - sails.js 为浏览器访问启用 csrf 并为 native 应用程序访问禁用 csrf

ios - 带有django csrf的ionic/angularjs可以在本地服务器上工作,但不能在设备上工作

c# - .NET Core AWS RDS 连接

c# - ASP.NET核心: Azure AD B2C self service password reset (sign-up/sign-in policy)