我在IIS中的单个站点上部署了几个ASP.net MVC应用程序。所有应用程序都使用表单身份验证,并且所有应用程序都配置为使用相同的计算机密钥。
其中一个应用程序是“基本站点”,它为其他应用程序提供导航,并且正在处理登录/注销功能。就目前而言,用户可以登录基站并访问其他应用程序,它们仍将进行身份验证,这是按预期工作的。
我在共享布局视图的标题中有一个注销表单,它向属于基站的控制器中的注销操作提交发布请求。当我从基站提交此表单时,注销按预期工作。但是,如果我尝试从任何其他网站提交表单,我会收到错误消息:
"The anti-forgery cookie token and form field token do not match."
这是我的安全控制器中的注销操作:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return Redirect("~/");
}
这是我的表单在基本站点视图中的样子:
using (Html.BeginForm("LogOff", "Security", FormMethod.Post, null))
{
@Html.AntiForgeryToken()
<input type="submit" value="Log Off"/>
}
由于目录的设置方式,其他站点使用相同表单的略有不同的版本来从基站调用注销操作:
using (Html.BeginForm("LogOff", "../Security", FormMethod.Post, null))
{
@Html.AntiForgeryToken()
<input type="submit" value="Log Off"/>
}
基本站点位于目录的根目录下,其他应用程序包含在该根目录中的自己的文件夹中。
我尝试过的所有观点都没有任何冲突形式或反伪造令牌,并且所有应用程序中的机器密钥似乎都配置正确,否则我认为身份验证根本不起作用。我正在考虑重新定向到基站并从那里执行注销操作,但是如果还有另一个更简单的解决方案,我还没有遇到过那样会很好。
答案 0 :(得分:0)
AntiForgeryToken
通过创建隐藏字段和具有相同令牌的Cookie来工作(请参阅this blod post)。由于您的表单被发布到另一个URL,我认为该cookie或者不与POST一起传输,或者您的浏览器仍然有一个cookie,从之前的请求到您的基站,因此传输错误的cookie。删除cookie后是否也会出现这种情况(确保没有使用旧的?)
答案 1 :(得分:0)
我为解决此问题所做的工作是将LogOff操作移动到我的所有控制器都已继承的自定义控制器类中。
public abstract class BaseController : Controller
{
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
//Redirect to home page when logging off.
return Redirect("~/");
}
}
然后只需更改我的注销表单以从当前控制器调用LogOff操作,而不是在基本站点中指定安全控制器:
using (Html.BeginForm("LogOff", "", FormMethod.Post, null))
{
@Html.AntiForgeryToken()
<input type="submit" value="Log Off"/>
}
我不确定是否有办法让我的原始版本能够正常工作,所以现在我觉得我会接受这个。