不推荐使用允许覆盖字符串路径的前
HtmlHelper.AntiForgeryToken方法.
[ObsoleteAttribute("This method is deprecated. Use the AntiForgeryToken() method instead. To specify a custom domain for the generated cookie,use the <httpCookies> configuration element. To specify custom data to be embedded within the token,use the static AntiForgeryConfig.AdditionalDataProvider property.",true)]
public MvcHtmlString AntiForgeryToken(
string salt,string domain,string path
)
告诉您使用< httpCookies>.但是httpCookies Element没有PATH的设置.
这是对这种方法的弃用的疏忽吗?覆盖此cookie路径的最佳方法是什么? (手动?)在虚拟应用程序中运行网站不会隐式地将应用程序路径添加到__RequestVeririfcation cookie.
解决方法
查看弃用消息:
“This method is deprecated. Use the AntiForgeryToken() method instead. To specify a custom domain for the generated cookie,use the configuration element. To specify custom data to be embedded within the token,use the static AntiForgeryConfig.AdditionalDataProvider property.”
它告诉我们,只要回读伪造令牌,我们就可以验证其他参数.因此,即使我们无法在cookie中设置路径,我们也可以将路径设置为令牌内的属性.稍后要验证它,例如:
public class AdditionalDataProvider : IAntiForgeryAdditionalDataProvider
{
public string GetAdditionalData(HttpContextBase context)
{
return AdditionalData(context);
}
public bool ValidateAdditionalData(HttpContextBase context,string additionalData)
{
var currentData = AdditionalData(context);
return currentData == additionalData;
}
private static string AdditionalData(HttpContextBase context)
{
var path = context.Request.ApplicationPath;
return path;
}
}
当asp.net生成令牌时,它将存储该应用程序的当前路径(或您要验证的任何其他唯一值)
如果你有另一个应用程序在不同的路径上运行,当令牌被发送到该应用程序时(由于缺少cookie路径),它将根据该应用程序的属性验证以前的应用程序属性.如果它是一组不同的属性,它将失败并拒绝该请求.
另外,查看AntiforgeryConfig.cs的代码,如果应用程序在虚拟目录中运行,它将默认在cookie的名称中添加该虚拟目录:
private static string GetAntiForgeryCookieName()
{
return GetAntiForgeryCookieName(HttpRuntime.AppDomainAppVirtualPath);
}
// If the app path is provided,we're generating a cookie name rather than a field name,and the cookie names should
// be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on
// each other.
internal static string GetAntiForgeryCookieName(string appPath)
{
if (String.IsNullOrEmpty(appPath) || appPath == "/")
{
return AntiForgeryTokenFieldName;
}
else
{
return AntiForgeryTokenFieldName + "_" + HttpServerUtility.UrlTokenEncode(Encoding.UTF8.GetBytes(appPath));
}
}
所以它会是这样的:
_RequestVerificationToken vs
_RequestVerificationToken_L2RIdjAz0
意思是App2虽然可以从App1接收令牌,但它将无法读取它们,因为它只会查找App2验证令牌.
HTH
