好吧,让我们看看 ValidateAntiforgeryTokenAttribute 做了什么(Reflector/ILSpy 是你的朋友):
公共无效 OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext == null)
{
抛出新的 ArgumentNullException("filterContext");
}
字符串 antiForgeryTokenName = AntiForgeryData.GetAntiForgeryTokenName(null);
字符串 antiForgeryTokenName2 = AntiForgeryData.GetAntiForgeryTokenName(filterContext.HttpContext.Request.ApplicationPath);
HttpCookie httpCookie = filterContext.HttpContext.Request.Cookies[antiForgeryTokenName2];
if (httpCookie == null || string.IsNullOrEmpty(httpCookie.Value))
{
抛出 ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
AntiForgeryData antiForgeryData = this.Serializer.Deserialize(httpCookie.Value);
字符串文本 = filterContext.HttpContext.Request.Form[antiForgeryTokenName];
如果(字符串。IsNullOrEmpty(文本))
{
抛出 ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
AntiForgeryData antiForgeryData2 = this.Serializer.Deserialize(text);
if (!string.Equals(antiForgeryData.Value, antiForgeryData2.Value, StringComparison.Ordinal))
{
抛出 ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
字符串用户名 = AntiForgeryData.GetUsername(filterContext.HttpContext.User);
if (!string.Equals(antiForgeryData2.Username, username, StringComparison.OrdinalIgnoreCase))
{
抛出 ValidateAntiForgeryTokenAttribute.CreateValidationException();
}
if (!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 解决方案,但如果你真的想要这个,你可以在几分钟内完成它。只需使用反射器和复制粘贴 :)