11

私が次のコードを入れているとき:

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

the

@Html.AntiForgeryToken()

一部は例外に続いてthrownigです:

タイプ'System.Web.Security.FormsIdentity'の提供されたIDは、IsAuthenticated = trueとマークされていますが、Nameの値はありません。デフォルトでは、偽造防止システムでは、認証されたすべてのIDに一意の名前が必要です。このIDに一意の名前を指定できない場合は、静的プロパティAntiForgeryConfig.AdditionalDataProviderを、現在のユーザーに何らかの形式の一意の識別子を提供できるタイプのインスタンスに設定することを検討してください。

多くの例を確認してウェブを検索しようとしましたが、説明が見つかりません。このエラーが発生する理由を知りたいのですが?そして、偽造防止を使用するためにそれを解決する方法。

4

2 に答える 2

7

ログインしているにもかかわらずMembership.GetUser().UserName、ハッシュに使用できる名前が提供されていないため、機能しないことを示しています。

だからあなたの本当の問題は、「どうして私のログインしたユーザーがユーザー名を持っていないのですか?」です。

于 2012-10-09T09:02:03.117 に答える
6

ログインしたユーザーにIdentity.Nameが設定されていない場合があります(私の場合、アプリをクレイジーなログインシステムと統合する必要があります)。次に、2つの方法があります。

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 に答える