我有2个网站,实际上它们是相同的。目的是其中一个针对互联网用户,第二个针对本地用户。
现在,它们托管在我的本地主机上的同一IIS服务器上。
当我打开这两个网站并尝试获得标有[ValidateAntiForgeryToken]的操作结果时,我遇到了一个问题,即我的cookie中有我的本地主机站点的cookie,并且有一个名为“ RequestVerificationToken_Lw”的cookie,这是防伪保护键。
问题在于两个站点都使用相同的cookie来存储此密钥。因此,如果在一个网站上进行了smth操作,则在尝试对另一个网站进行smth操作时出现了防伪错误。

如何更改Cookie域或任何其他解决方案来拆分Cookie?

谢谢!

最佳答案

好吧,让我们看看ValidateAntiforgeryTokenAttribute的作用(Reflector / ILSpy是您的朋友):

公共无效OnAuthorization(AuthorizationContext filterContext)
{
如果(filterContext == null)
{
抛出新的ArgumentNullException(“ filterContext”);
}
字符串antiForgeryTokenName = AntiForgeryData.GetAntiForgeryTokenName(null);
字符串antiForgeryTokenName2 = AntiForgeryData.GetAntiForgeryTokenName(filterContext.HttpContext.Request.ApplicationPath);
HttpCookie httpCookie = filterContext.HttpContext.Request.Cookies [antiForgeryTokenName2];
如果(httpCookie == null || string.IsNullOrEmpty(httpCookie.Value))
{
抛出ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
AntiForgeryData antiForgeryData = this.Serializer.Deserialize(httpCookie.Value);
字符串文本= filterContext.HttpContext.Request.Form [antiForgeryTokenName];
如果(string.IsNullOrEmpty(text))
{
抛出ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
AntiForgeryData antiForgeryData2 = this.Serializer.Deserialize(text);
如果(!string.Equals(antiForgeryData.Value,antiForgeryData2.Value,StringComparison.Ordinal))
{
抛出ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
字符串用户名= AntiForgeryData.GetUsername(filterContext.HttpContext.User);
如果(!string.Equals(antiForgeryData2.Username,username,StringComparison.OrdinalIgnoreCase))
{
抛出ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
如果(!this.ValidateFormToken(antiForgeryData2))
{
抛出ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
}


好的,很明显,令牌的cookie名称是从应用程序路径生成的:

字符串antiForgeryTokenName2 = AntiForgeryData.GetAntiForgeryTokenName(filterContext.HttpContext.Request.ApplicationPath);
HttpCookie httpCookie = filterContext.HttpContext.Request.Cookies [antiForgeryTokenName2];



因此,您创建自己的过滤器,只需复制粘贴此代码,然后将其更改为也要考虑端口(或根据您区分应用程序的方式而定):

字符串antiForgeryTokenName2 = AntiForgeryData.GetAntiForgeryTokenName(filterContext.HttpContext.Request.ApplicationPath + filterContext.HttpContext.Request.Url.Port);
HttpCookie httpCookie = filterContext.HttpContext.Request.Cookies [antiForgeryTokenName2];


这样,cookie名称(“ RequestVerificationToken_Lw”)也将因端口而异。

当然,我们也不能忘记在创建令牌时更改此cookie名称。不幸的是,您将需要在此处复制粘贴“重新实现”两件事-首先是AntiForgeryToken扩展方法来调用您自己的AntiForgeryWorker,然后是AntiForgeryWorker本身-只是重写方法GetAntiForgeryTokenAndSetCookie,它和以前一样:

字符串antiForgeryTokenName = AntiForgeryData.GetAntiForgeryTokenName(httpContext.Request.ApplicationPath);


好吧,这似乎是一团糟,而且绝对不是DRY解决方案,但是如果您真的想要这个,可以在几分钟内完成。只需使用反射器并复制粘贴即可:)

08-19 09:33