ValidateAntiForgeryToken 400 错误使用角度 13 和 ASP.NET 核心 5

Posted

技术标签:

【中文标题】ValidateAntiForgeryToken 400 错误使用角度 13 和 ASP.NET 核心 5【英文标题】:ValidateAntiForgeryToken 400 error Using angular 13 and ASP.NET core 5 【发布时间】:2022-01-01 13:09:02 【问题描述】:

我正在使用 Angular 13 和 ASP.Net Core5。我正在尝试使用 ValidateAntiForgeryToken 属性并且总是得到 400 错误。在我发布这个问题之前,我尝试了几乎所有在互联网上找到的解决方案。但是,我想澄清一下我的情况,我正在创建一个多租户应用程序。每个企业主都将拥有一个子域和单独的数据库。我不知道 Antiforgery 令牌是否由于这种情况而无法正常工作,但我尝试了 3 天的许多解决方案。

Startup.cs

services.AddAntiforgery(options =>
            
                options.Cookie.Name = "XSRF-TOKEN";
                options.HeaderName = "X-XSRF-TOKEN";
                options.Cookie.HttpOnly = false;
            );

我使用了这个配置并且 ASP.NET 发送了名为 XSRF-TOKEN 的防伪 cookie。根据 Angular 文档,如果存在名为 X-XSRF-TOKEN 的 cookie,Angular 将发送一个名为 X-XSERF-TOKEN 的标头。实际上,Angular 每次请求都成功发送了它,但我仍然收到代码 400 的错误。

我尝试手动添加 X-XSRF-TOKEN。我尝试使用以下中间位置

app.Use(next => context =>
            
                if (
                    string.Equals(context.Request.Path.Value, "/", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(context.Request.Path.Value, "/index.html", StringComparison.OrdinalIgnoreCase) ||
                    string.Equals(context.Request.Path.Value, "/api", StringComparison.OrdinalIgnoreCase))
                
                    // We can send the request token as a javascript-readable cookie, and Angular will use it by default.
                    var tokens = antiForgery.GetAndStoreTokens(context);
                    context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
                        new CookieOptions()  HttpOnly = false, Secure = false );
                

                return next(context);
            );

我尝试在 startup.cs 中使用 CORS

services.AddCors(c => c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod()); );

app.UseCors(policy =>
           
              policy.AllowAnyOrigin();
              policy.AllowAnyHeader();
              policy.AllowAnyMethod();
           );

然后为控制器添加[EnableCors(PolicyName = "AllowOrigin")]

我尝试了这些解决方案的组合,但仍然遇到同样的错误。

【问题讨论】:

【参考方案1】:

最后,我发现了问题所在。我的情况是我为每个企业主创建了一个子域和不同的数据库。 [ValidateAntiForgeryToken] 适用于以下配置: 在配置服务中:

services.AddAuthentication(x =>
            
                x.DefaultAuthenticateScheme = IdentityConstants.ApplicationScheme;
                x.DefaultChallengeScheme = IdentityConstants.ApplicationScheme;
            )
            .AddCookie(IdentityConstants.ApplicationScheme)
            .AddJwtBearer(x =>
            
                x.RequireHttpsMetadata = false;
                x.TokenValidationParameters = new TokenValidationParameters()
                
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["TokenKey"])),
                    ValidateIssuer = false,
                    ValidateAudience = false
                ;
            );

在配置中:

app.Use(next => context =>
            
                if (context.Request.Path.Value.IndexOf("/api", StringComparison.OrdinalIgnoreCase) != -1)
                
                    var tokens = antiForgery.GetAndStoreTokens(context);
                    context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
                        new CookieOptions()  HttpOnly = false, Secure = false );
                

                return next(context);
            );

但是,如果没有 Authorize 属性 [Authorize],这将有效。 因此,我使用 [Authorize] 和 [ValidateAntiForgeryToken] 的解决方案是创建自定义 Antiforgery 令牌属性。 我使用此问题中的解决方案创建了自定义 AntiForgeryToken https://***.com/a/28526906/14474303。 但要小心,如果你的控制器类继承自ControllerBase,这意味着你使用Microsoft.AspNetCore.Mvc;,但如果它继承自ApiController,那么你使用的是System.Web.Http。此链接中的解决方案是使用 System.Web.Http,如果您使用的是 `Microsoft.AspNetCore.Mvc,它将无法正常工作。

简单地说,如果您要创建自定义 Antiforgery 令牌,您的自定义类将继承自 ActionFilterAttribute。所以,如果你使用System.Web.Http,那么ActionFilterAttribute将从System.Web.Http导入,但是,如果你使用Microsoft.AspNetCore.Mvc,那么ActionFilterAttribute将从`Microsoft.AspNetCore.Mvc导入。

【讨论】:

你试过降级到 netcore 3.1x 吗?我有同样的问题,但我使用的是 3.1 和 mvc,但我的库是 Identity Core,EF Identity 是 ver5。我尝试从 JwtBearerDefaults 更改为 IdentityConstants。我在运行时遇到错误,你建议解决什么?,你能提供你所有的配置服务吗,我已经有几天试图解决这个问题,在登录中附加 cookie,不同的 cors,刚才我得到代码 404。 @AbbathCL 实际上,我按照以下 youtube 播放列表youtube.com/… 中的建议使用 Cookie 进行身份验证 我发现secure必须设置为true才能在浏览器中设置cookie,同样在HttpRequest中需要添加withCredentials:true。

以上是关于ValidateAntiForgeryToken 400 错误使用角度 13 和 ASP.NET 核心 5的主要内容,如果未能解决你的问题,请参考以下文章

如何全局设置 ValidateAntiForgeryToken

Web API 和 ValidateAntiForgeryToken

ValidateAntiforgeryToken 失败

ValidateAntiForgeryToken 400 错误使用角度 13 和 ASP.NET 核心 5

如何正确使用ValidateAntiForgeryToken?

带有 SPA 架构的 ValidateAntiForgeryToken