ASP.Net MVC上的防伪系统

当我输入以下代码时:

@using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) { @Html.AntiForgeryToken() Log off } 

 @Html.AntiForgeryToken() 

部分是exception后抛出的:

提供的“System.Web.Security.FormsIdentity”类型的标识标记为IsAuthenticated = true,但没有Name的值。 默认情况下,防伪系统要求所有经过身份validation的身份都具有唯一的名称。 如果无法为此标识提供唯一的名称,请考虑将静态属性AntiForgeryConfig.AdditionalDataProvider设置为可为当前用户提供某种forms的唯一标识符的类型的实例。

我查了很多例子并尝试搜索网页,但我找不到任何解释。 我想知道为什么这个错误发生在我身上? 如何解决它使用防伪。

它告诉你它不会工作,因为尽管登录了Membership.GetUser().UserName没有提供可用于散列的名称。

所以你真正的问题是,“我的登录用户怎么没有用户名?”

在某些情况下,当登录用户没有设置Identity.Name时(在我的情况下,我必须将我的应用程序与一些疯狂的登录系统集成)。 然后有两种方法:

1)不安全 – 反伪造系统将以相同的方式对待所有用户,无论其身份validation状态如何

 // System.Web.WebPages.dll using System.Web.Helpers; // not a production solution public class MvcApplication : HttpApplication { protected void Application_Start() { AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; } } 

2)安全 – 提供您自己(自定义)的方式来区分您的用户

 using System; using System.Globalization; using System.Web; using System.Web.Helpers; public class ContoscoAntiForgeryAdditionalDataProvider : IAntiForgeryAdditionalDataProvider { public string GetAdditionalData(HttpContextBase context) { if (context == null) { throw new ArgumentNullException("context"); } var contoscoContext = new ContoscoHttpContext(context); int userID = contoscoContext.GetUserID().GetValueOrDefault(); return Convert.ToString(userID, CultureInfo.InvariantCulture); } public bool ValidateAdditionalData(HttpContextBase context, string additionalData) { string data = GetAdditionalData(context); return string.Compare(data, additionalData, StringComparison.Ordinal) == 0; } } public class MvcApplication : HttpApplication { protected void Application_Start() { AntiForgeryConfig.AdditionalDataProvider = new ContoscoAntiForgeryAdditionalDataProvider(); } } 

其中ContoscoHttpContext是基于当前上下文(即HttpContextBase )返回UserID(或任何唯一用户令牌)的类:

 public class ContoscoHttpContext { private HttpContextBase _context; public ContoscoHttpContext(HttpContextBase context) { _context = context; } public int? GetUserID() { // TODO: provide your own implementation how to get user id // based on HttpContextBase stored in _context // in my case it was something like // return ((ContoscoPrincipal)_context.User).UserID; } }