MVC3 AntiForgeryToken打破了Ajax登录 [英] MVC3 AntiForgeryToken breaks on Ajax login

查看:338
本文介绍了MVC3 AntiForgeryToken打破了Ajax登录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ASP.NET MVC的 AntiForgeryToken 机制是基于当前的 HttpContext.User中。它使用的价值,当你调用构造标记 Html.AntiForgeryToken()。基本上,它是确定(参见解释末段这里),但出现问题当你通过 Ajax调用日志

ASP.NET MVC's AntiForgeryToken mechanism is based on the current HttpContext.User. It uses that value to construct the token when you call Html.AntiForgeryToken(). Basically it is OK (see an explanation in the last paragraph here) but a problem arises when you log in through an Ajax call.

在我的code,当用户登录时,该证书将作为在埃杰克斯( AntiForgeryToken 隐藏字段的值也被内部发送的JSON对象JSON),服务器对用户进行认证,适用FormsAuthentication.SetAuthCookie(),并返回一个JSON结果,其中包含某些用户特定的数据。这样一来,我可以在登录时避免整页刷新。

In my code, when a user logs in, the credentials are sent as a Json object in Ajax (the AntiForgeryToken hidden field value is also sent inside the Json), the server authenticates the user, applies FormsAuthentication.SetAuthCookie(), and returns a Json result which contains some user-specific data. In that way, I can avoid full page refresh upon login.

现在的问题是,每一个后续Ajax请求到服务器现在无法在 ValidateAntiForgeryTokenAttribute ,因为它现在预计的防伪令牌与防伪的cookie不兼容

The problem is that every subsequent Ajax request to the server now fails upon ValidateAntiForgeryTokenAttribute, because it now expects an anti-forgery token that is incompatible with the anti-forgery cookie.

我怎样才能得到有效的防伪标记将在客户端的隐藏字段,以便登录后每JSON请求会成功吗?

我试图令牌手动得到一个新的隐藏字段(使用 AntiForgery.GetHtml()的行动,提取令牌字符串本身,将其返回到客户端JSON和将其放置在防伪隐藏字段手动在JavaScript中),但它不工作 - 对 ValidateAntiForgeryTokenAttribute 服务器上的一个后续Ajax调用失败。 事实上,每次调用 AntiForgery.GetHtml()(这基本上是什么 Html.AntiForgeryToken()助手完成)产生不同的令牌,其中previous 1无效。

I tried to get a new hidden-field token manually (using AntiForgery.GetHtml() on the action, extracting the token string itself, returning it to the client in Json and placing it in the anti-forgery hidden field manually in JavaScript) but it does not work - a subsequent Ajax call fails on the ValidateAntiForgeryTokenAttribute on the server. In fact, every call to AntiForgery.GetHtml() (which is essentially what Html.AntiForgeryToken() helper does) produces a different token, which invalidates the previous one.

我也试着设置 HttpContext.User中=新的GenericPrincipal(新GenericIdentity(电子邮件),NULL); 详见<一个href="http://stackoverflow.com/questions/7233939/mvc3-antiforgerytoken-issue/7238884#7238884">here,但它不工作

I also tried to set HttpContext.User = new GenericPrincipal(new GenericIdentity(email), null); as detailed here, but it doesn't work.

注意: <一个href="http://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken/4074289#4074289">This解决方案对我来说,行不通的,因为我的具体情况:一个Ajax的登录的这改变了服务器,因此每一个生成之前的登录无效令牌上的用户身份; <一href="http://stackoverflow.com/questions/1347728/using-an-mvc-htmlhelper-from-a-webform/2553583#2553583">this解决方案还并不适用,因为它解决不同的问题。

Note: This solution doesn't work for me, because of my specific situation: An Ajax login which changes the user identity on the server and hence every token that was generated before the login is invalid; this solution also doesn't apply because it addresses a different problem.

推荐答案

您将需要清除和重做任何现有形式的标记必须登录后。这意味着您的登录code将不得不要么刷新当前页面(还挺杀死它的AJAX部分诶),你自己的令牌实现,否则你将需要刷新令牌。它可以请求局部视图,提取令牌,并更新您的形式。其实你可以有一个宁静的URL,它返回只是一个令牌身份验证的用户。有人可能会说,这是一个安全问题,但我不这么认为,因为它只是一个简单的方法来获得一个令牌,而不是请求的任何观点-partial或以其他方式。

You will need to clear and redo any existing form token you have upon login. This means your login code will have to either refresh the current page (kinda kills the ajax portion of it eh), your own token implementation, or you will need to refresh your token. It is possible to request a partial view, extract the token, and update your form. You could actually have a restful url which returns nothing but a token to an authenticated user. One may argue this is a security issue, but I don't believe so because it is simply an easier way to get a token rather than requesting any view -partial or otherwise.

您应该能够轻松获得令牌通过实例来代替:

You should be able to easily get the token instances to replace via:


var token = $('input[name=""__RequestVerificationToken""]');

编辑 在重新阅读了几次 - 我怀疑

EDIT After re-reading a few more times - I question

为什么你的窗体上的标记,如果没有登录,您允许相同的形式来'工作',而没有登录和登录的用户?大多数网站上的净,即使在这种情况下,将重定向进行登录。难道我理解这是否正确?如果是这样,你可能要考虑这里跳过令牌或使用第二个类型的标记为未认证用户。你相信我在说一个未经身份验证的用户已经可以提交一些应用程序 - 再次,如果我理解这个正确的 - 不认证

Why would you have a token on the form if the user isn't logged in. You allow the same form to be 'operated' while not logged in and logged in? Most sites on the net even in this case will redirect for a login. Am I understanding this correctly? If so, you may want to consider skipping the token here or use a second type of token for unauthenticated users. You I believe are saying an unauthenticated user can already submit something in the application - again if I understand this correctly - without being authenticated.

这篇关于MVC3 AntiForgeryToken打破了Ajax登录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆