C# 基于ASP.NETMVC的防伪系统

C# 基于ASP.NETMVC的防伪系统,c#,asp.net-mvc,C#,Asp.net Mvc,当我输入以下代码时: @using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" })) { @Html.AntiForgeryToken() <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a> } 零件有

当我输入以下代码时:

 @using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" }))
    {
        @Html.AntiForgeryToken()
        <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a>
    }
零件有以下例外情况:

提供的类型为“System.Web.Security.FormsIdentity”的标识标记为IsAuthenticated=true,但没有名称值。默认情况下,防伪系统要求所有经过身份验证的身份都具有唯一的名称。如果无法为该标识提供唯一的名称,请考虑将静态属性AuthFoGyyCuff.AudioTalDATAdvalvor设置为可以为当前用户提供某种形式的唯一标识符的类型的实例。
我查了很多例子,并试图在网上搜索,但我找不到任何解释。我想知道为什么这个错误会发生在我身上?以及如何使用Antifforgery解决问题。

它告诉您,尽管已登录,
Membership.GetUser().UserName
未提供可用于哈希的名称,因此它将无法工作


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

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

1) 不安全-无论用户的身份如何,反伪造系统都将以相同的方式对待他们

// 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
)返回用户ID(或任何唯一用户令牌)的类:


我真正的问题是“为什么我的用户在我第一次开始调试时就登录了?”这是AntiForgeryConfig.SuppressIdentityEuristicChecks(带“s”)。ContoCoHttpContext做什么?@slolife-updated;我希望它现在能解释ContoscoHttpContext的含义。基本上,它是一个基于当前上下文返回UserID的组合类。
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(); 
  }
}
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;
  }
}