11

当我输入以下代码时:

 @using (Html.BeginForm("LogOff", "Account", FormMethod.Post, new { id = "logoutForm" }))
    {
        @Html.AntiForgeryToken()
        <a href="javascript:document.getElementById('logoutForm').submit()">Log off</a>
    }

@Html.AntiForgeryToken()

部分被抛出以下异常:

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

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

4

2 回答 2

7

它告诉您它不起作用,因为尽管已登录,但Membership.GetUser().UserName没有提供可用于散列的名称。

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

于 2012-10-09T09:02:03.117 回答
6

在某些情况下,登录用户没有设置 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根据当前上下文(即)返回 UserID(或任何唯一用户令牌)的类在哪里HttpContextBase

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;
  }
}
于 2014-02-14T13:48:42.233 回答