Ofe*_*lig 8 security ajax asp.net-mvc antiforgerytoken asp.net-mvc-3
ASP.NET MVC的AntiForgeryToken机制基于当前HttpContext.User.它在您调用时使用该值来构造令牌Html.AntiForgeryToken().基本上没关系(请参阅此处最后一段中的解释)但是当您通过Ajax调用登录时会出现问题.
在我的代码中,当用户登录时,凭据在Ajax中作为Json对象发送(AntiForgeryToken隐藏字段值也在Json内发送),服务器验证用户,应用FormsAuthentication.SetAuthCookie(),并返回Json结果包含一些用户特定的数据.这样,我可以在登录时避免整页刷新.
问题是现在每个后续的Ajax请求都会失败ValidateAntiForgeryTokenAttribute,因为它现在需要一个与防伪cookie不兼容的防伪标记.
如何将有效的防伪标记放入客户端的隐藏字段中,以便登录后的每个Json请求都会成功?
我试图手动获取一个新的隐藏字段标记(AntiForgery.GetHtml()在操作上使用,提取标记字符串本身,将其返回到Json中的客户端并在JavaScript中手动将其放置在防伪隐藏字段中)但它不起作用 - ValidateAntiForgeryTokenAttribute服务器上的后续Ajax调用失败.事实上,每次调用AntiForgery.GetHtml()(基本上是Html.AntiForgeryToken()帮助程序所做的)都会产生一个不同的令牌,这会使前一个令牌失效.
我也试着设置HttpContext.User = new GenericPrincipal(new GenericIdentity(email), null);详见这里,但它不工作.
注意: 由于我的具体情况,此解决方案对我不起作用:Ajax 登录更改服务器上的用户身份,因此登录前生成的每个令牌都无效; 此解决方案也不适用,因为它解决了不同的问题.
您需要清除并重做登录时的任何现有表单令牌.这意味着您的登录代码必须刷新当前页面(有点杀死它的ajax部分),您自己的令牌实现,或者您需要刷新令牌.可以请求部分视图,提取令牌和更新表单.你实际上可以有一个restful url,它只向经过身份验证的用户返回一个令牌.有人可能会说这是一个安全问题,但我不相信,因为它只是一种获取令牌的简单方法,而不是请求任何视图 - 部分或其他方式.
您应该能够通过以下方式轻松获取要替换的令牌实例:
var token = $('input[name=""__RequestVerificationToken""]');
编辑重新阅读几次后 - 我提出质疑
如果用户没有登录,为什么你会在表单上有一个令牌.你允许在没有登录和登录的情况下"操作"同一个表单?即使在这种情况下网络上的大多数网站都将重定向登录.我理解正确吗?如果是这样,您可能需要考虑在此处跳过令牌或对未经身份验证的用户使用第二种类型的令牌.你我相信一个未经身份验证的用户已经可以在应用程序中提交一些内容 - 如果我理解正确的话 - 再次进行身份验证.
| 归档时间: |
|
| 查看次数: |
3549 次 |
| 最近记录: |