为什么AntiForgeryTokenvalidation会失败?

我正在开发一个使用asp.net core2Angular运行的web API应用程序。 详细的开发环境配置在这里 。 我正在尝试配置AntiForgeryTokenvalidation但它仍然失败。 我按照配置。 在这里 ,但我必须修改它,因为我的角度应用程序和asp.net服务器在两个不同的端口上运行,因为前端启动不会生成令牌。 我通过在应用程序组件ngOnInit中调用API路径( /api/Account/ContactInitialization )来启动后端,这允许我生成令牌。 配置如下所示,

IServiceCollection服务:

  services.AddAntiforgery(options => { options.HeaderName = "X-CSRF-TOKEN"; options.SuppressXFrameOptionsHeader = false; }); 

并在IApplicationBuilder Configure

 app.Use(next => context => { string path = context.Request.Path.Value; if ( string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) || string.Equals(path, "/api/Account/ContactInitialization", StringComparison.OrdinalIgnoreCase) || string.Equals(path, "/index.html", 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 }); } return next(context); }); 

asp.net。 生成两组键,

在此处输入图像描述

我用[ValidateAntiForgeryToken]修饰了我的方法,并在头文件请求中包含了XSRF-TOKEN cookie内容。 但在调用API后我仍然收到400 (Bad Request)响应! 我在这里错过了什么?

控制器方法,

  [Authorize] [ValidateAntiForgeryToken] [HttpPost] public IEnumerable AutherizeCookie() { return new string[] { "Hello", "Auth Cookie" }; } 

我的详细标题请求如下所示,

标题请求

我假设你可能跟着文档 ,但是掩盖了相关的部分。 到目前为止你所做的只适用于Angular,因为Angular的$http实际上会根据XSRF-TOKEN cookie添加X-XSRF-TOKEN头。 (但是,请注意,即使这样,您也将标题设置为X-CSRF-TOKEN ,这在这里实际上不起作用。它需要是X-XSRF-TOKEN )。

但是,如果您没有使用Angular,那么您有责任在AJAX请求中自己设置标头,这可能是您忽略的。 在这种情况下,您实际上不需要更改任何防伪令牌配置(标题名称,设置cookie等)。 您只需要将标头提供为RequestVerificationToken 。 例如,使用jQuery:

 $.ajax({ ... headers: { "RequestVerificationToken": '@GetAntiXsrfRequestToken()' }, ... }); 

这将适用于JavaScript。 如果你需要在外部JS中执行此操作,那么您需要设置cookie,以便您可以从cookie中获取值。 除此之外,适用相同的方法。

如果您只是想更改标题名称,则可以这样做; 您只需将RequestVerificationHeader部分更改为相同的值即可。

您需要发出XHR请求withCredentials = true,这将使浏览器设置cookie,否则您将获得400错误请求,因为cookie不存在且X-XSRF-TOKEN未设置或设置为空字符串

谢谢,@ Chris_Pratt指出了我的标题问题。 但是,为了说清楚,我还有其他问题需要解决。

我的CORS配置错误,我的工作代码如下,

 services.AddCors(options => { options.AddPolicy("CorsPolicy", builder => builder .WithOrigins("https://www.artngcore.com:4200") //Note: The URL must be specified without a trailing slash (/). .AllowAnyMethod() .AllowAnyHeader() .AllowCredentials()); }); services.AddAntiforgery(options => { options.HeaderName = "X-XSRF-TOKEN"; options.SuppressXFrameOptionsHeader = false; }); 

middleware配置是,

 app.Use(next => context => { string path = context.Request.Path.Value; var tokens = antiforgery.GetAndStoreTokens(context); context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken, new CookieOptions() { HttpOnly = false, Secure = true // set false if not using SSL }); return next(context); }); 

在控制器中

 [Route("/api/[controller]/[action]")] [EnableCors("CorsPolicy")] public class AccountController : ArtCoreSecuredController .... 

这里的诀窍是令牌必须在认证后刷新。 在身份validation(登录)之后调用API将执行此操作。 不要忘记在您的请求中添加以下标题,

  const headers = new HttpHeaders({ 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.cookieService.get('ArtCoreToken')}`, 'X-XSRF-TOKEN': `${this.cookieService.get('XSRF-TOKEN')}` }); 

  [HttpGet] [AllowAnonymous] public async Task RefreshToken() { await Task.Delay(1); return StatusCode(200); } 

这对我有用。 希望能帮助到你。