对防伪令牌问题进行故障排除 [英] Troubleshooting anti-forgery token problems
问题描述
我有一个表单帖子,它一直给我一个防伪令牌错误.
I have a form post that consistently gives me an anti-forgery token error.
这是我的表格:
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.EditorFor(m => m.Email)
@Html.EditorFor(m => m.Birthday)
<p>
<input type="submit" id="Go" value="Go" />
</p>
}
这是我的操作方法:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Join(JoinViewModel model)
{
//a bunch of stuff here but it doesn't matter because it's not making it here
}
这是 web.config 中的 machineKey:
Here is the machineKey in web.config:
<system.web>
<machineKey validationKey="mykey" decryptionKey="myotherkey" validation="SHA1" decryption="AES" />
</system.web>
这是我得到的错误:
A required anti-forgery token was not supplied or was invalid.
我已经读到更改 HttpContext 上的用户会使令牌无效,但这里不会发生这种情况.我的 Join 操作上的 HttpGet 只是返回视图:
I've read that changing users on the HttpContext will invalidate the token, but this isn't happening here. The HttpGet on my Join action just returns the view:
[HttpGet]
public ActionResult Join()
{
return this.View();
}
所以我不确定发生了什么.我四处搜索,似乎一切都表明它是机器密钥更改(应用程序周期)或用户/会话更改.
So I'm not sure what's going on. I've searched around, and everything seems to suggest that it's either the machineKey changing (app cycles) or the user/session changing.
还有什么可能发生?我该如何解决这个问题?
What else could be going on? How can I troubleshoot this?
推荐答案
在 Adam 的帮助下,我将 MVC 源代码添加到我的项目中,并且能够看到有很多情况导致相同的错误.
After help from Adam, I get the MVC source added to my project, and was able to see there are many cases that result in the same error.
这里是用于验证防伪令牌的方法:
Here is the method used to validate the anti forgery token:
public void Validate(HttpContextBase context, string salt) {
Debug.Assert(context != null);
string fieldName = AntiForgeryData.GetAntiForgeryTokenName(null);
string cookieName = AntiForgeryData.GetAntiForgeryTokenName(context.Request.ApplicationPath);
HttpCookie cookie = context.Request.Cookies[cookieName];
if (cookie == null || String.IsNullOrEmpty(cookie.Value)) {
// error: cookie token is missing
throw CreateValidationException();
}
AntiForgeryData cookieToken = Serializer.Deserialize(cookie.Value);
string formValue = context.Request.Form[fieldName];
if (String.IsNullOrEmpty(formValue)) {
// error: form token is missing
throw CreateValidationException();
}
AntiForgeryData formToken = Serializer.Deserialize(formValue);
if (!String.Equals(cookieToken.Value, formToken.Value, StringComparison.Ordinal)) {
// error: form token does not match cookie token
throw CreateValidationException();
}
string currentUsername = AntiForgeryData.GetUsername(context.User);
if (!String.Equals(formToken.Username, currentUsername, StringComparison.OrdinalIgnoreCase)) {
// error: form token is not valid for this user
// (don't care about cookie token)
throw CreateValidationException();
}
if (!String.Equals(salt ?? String.Empty, formToken.Salt, StringComparison.Ordinal)) {
// error: custom validation failed
throw CreateValidationException();
}
}
我的问题是将身份用户名与表单令牌的用户名进行比较的情况.就我而言,我没有设置用户名(一个为空,另一个为空字符串).
My problem was that condition where it compares the Identity user name with the form token's user name. In my case, I didn't have the user name set (one was null, the other was an empty string).
虽然我怀疑很多人会遇到同样的情况,但希望其他人会发现查看正在检查的潜在条件很有用.
While I doubt many will run into this same scenario, hopefully others will find it useful seeing the underlying conditions that are being checked.
这篇关于对防伪令牌问题进行故障排除的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!