ASP.net MVC跨应用程序POST请求

时间:2016-04-19 20:18:12

标签: c# asp.net-mvc iis antiforgerytoken

我在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"/>
                } 

基本站点位于目录的根目录下,其他应用程序包含在该根目录中的自己的文件夹中。

我尝试过的所有观点都没有任何冲突形式或反伪造令牌,并且所有应用程序中的机器密钥似乎都配置正确,否则我认为身份验证根本不起作用。我正在考虑重新定向到基站并从那里执行注销操作,但是如果还有另一个更简单的解决方案,我还没有遇到过那样会很好。

2 个答案:

答案 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"/>
                } 

我不确定是否有办法让我的原始版本能够正常工作,所以现在我觉得我会接受这个。