angularjs – .net核心MVC:X-SRF-TOKEN不被接受,400返回
我有一个使用angularJS的.net核心应用程序,我想保护受基于cookie的身份验证保护的api调用.我按照本文中的步骤操作:
https://docs.microsoft.com/en-us/aspnet/core/security/anti-request-forgery >我添加了services.AddAntiforgery(options => options.HeaderName =“X-XSRF-TOKEN”);到我的服务配置 我可以按预期通过此api端点使GET请求正常.但是,我收到400错误,没有任何有关PUT和POST请求错误的详细信息. 我知道X-XSRF-TOKEN是请求的(在chrome dev工具的网络选项卡中看到)所以我不确定我缺少什么来允许正确接收这些请求. TL; DR:为什么.net核心拒绝我的有效AntiforgeryToken? 更新尝试@ joey建议的解决方案,但它没有工作,仍然收到400个响应.下面的代码反映了我试图解决这个问题的另一个解决方案(aka angularjs的解决方案,为跨站点脚本保护设置默认cookie和标头) 我还尝试配置AngularJS以更改cookie和标题名称与我在Startup.cs中配置的名称相匹配的内容.我更改了他们的名字以尝试XSRF-TOKEN(cookie)和X-XSRF-TOKEN(标题)以及CSRF-TOKEN和X-CSRF-TOKEN,而angular内的配置正确地使用了新的默认值我提供,我在.net核心中的身份验证代码仍然无效. 有关更多信息,请参阅我如何配置AngularJS: app.config(function ($httpProvider) { $httpProvider.defaults.xsrfHeaderName = 'X-CSRF-TOKEN'; $httpProvider.defaults.xsrfCookieName = 'CSRF-TOKEN'; }); 这是我在Startup.cs文件中的ConfigureServices行: services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN"); 最后这是我添加到Startup.cs文件的Configure方法的代码: app.Use(next => context => { string path = context.Request.Path.Value; if (path.Contains("/MyProtectedPath/")) { var tokens = antiforgery.GetAndStoreTokens(context); context.Response.Cookies.Append("CSRF-TOKEN",tokens.RequestToken,new CookieOptions { HttpOnly = false }); } return next(context); }); 更新2: if (HttpContext.Request.Method.ToLower(CultureInfo.InvariantCulture) != "get") { await _antiforgery.ValidateRequestAsync(HttpContext); } AntiforgeryValidationException:提供的防伪令牌适用于与当前用户不同的基于声明的用户. 我想也许是antiforgery.GetAndStoreTokens(上下文)可能会覆盖页面加载时发送的当前cookie,所以我只让它在GET请求上点击该代码,但我得到的帖子结果相同. 更新3 app.Use(next => context => //note: order of these use statements is key. keep this antiforgery section above auth! { string path = context.Request.Path.Value; if (path.ToLower(CultureInfo.InvariantCulture).Contains("/campaigns/proxy/")) { var tokens = antiforgery.GetAndStoreTokens(context); context.Response.Cookies.Append("XSRF-TOKEN",new CookieOptions { HttpOnly = false }); } return next(context); }); // Use Basic Auth for /api app.UseWhen(context => context.Request.Path.StartsWithSegments(new PathString("/api")),branch => { branch.UseBasicAuth(); }); // Use Identity for everything except /api app.UseWhen(context => !context.Request.Path.StartsWithSegments(new PathString("/api")),branch => { app.UseAuthentication(); // required for .net core 2.0 authentication }); 我不确定为什么我的令牌在这一点上会被视为无效…… 解决方法
在您发布的代码中,您要添加标题X-XSRF-TOKEN,但标题应为X-CSRF-TOKEN.
您链接的网页中的示例提供了示例: services.AddAntiforgery(options => options.HeaderName = "X-CSRF-TOKEN"); 更新: 感谢您使用附加代码和&信息.这里选择的实现CSRF的方法是将标记作为初始HTML文件响应的标题传递的方法.以下是如何为SPA Web应用程序配置此类案例的示例: app.Use(next => context => { string path = context.Request.Path.Value; if ( string.Equals(path,"/",StringComparison.OrdinalIgnoreCase) || string.Equals(path,"/index.html",StringComparison.OrdinalIgnoreCase) ) { var tokens = antiforgery.GetAndStoreTokens(context); context.Response.Cookies.Append("CSRF-TOKEN",new CookieOptions() { HttpOnly = false }); } return next(context); }); 但是,将服务配置为使用String.Contains方法[1],将为包含/ MyProtectedPath / anywhere的任何路径调用antiforgery.GetAndStoreTokens(context).这意味着它的配置方式不仅与/ MyProtectedPath /匹配,还与/ MyProtectectedPath / a / b / c或/ a / b / c / MyProtectedPath /匹配. 检查在适用的HTTP方法的后续请求中发送的CSRF令牌,如下所示: if (string.Equals("POST",context.Request.Method,StringComparison.OrdinalIgnoreCase)) { await antiforgery.ValidateRequestAsync(context); // The line above will throw if the CSRF token is invalid. } 如果在此之前为任何匹配路径调用GetAndStoreTokens方法,则在检查之前将覆盖该令牌,这就是为什么.net示例通常首先命令GetAndStoreTokens,但具有查看路径和HTTP方法的特定条件. [1] https://msdn.microsoft.com/en-us/library/dy85x1sa(v=vs.110).aspx (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |