2012-10-09 97 views
10

當我把下面的代碼:反僞造系統MVC

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

@Html.AntiForgeryToken() 

部分thrownig以下異常:

類型的提供身份'System.Web.Security.FormsIdentity'被標記爲IsAuthenticated = true,但沒有Name的值。默認情況下,防僞系統要求所有經過身份驗證的身份都有唯一的名稱。如果無法爲此標識提供唯一名稱,請考慮將靜態屬性AntiForgeryConfig.AdditionalDataProvider設置爲可爲當前用戶提供某種形式的唯一標識符的類型實例。

我檢查了很多例子,並試圖搜索網頁,但我找不到任何解釋。我想知道爲什麼這個錯誤發生在我身上?以及如何解決它使用防僞。

回答

6

它告訴你它不起作用,因爲儘管已經登錄,Membership.GetUser().UserName沒有提供可用於哈希的名稱。

所以你真正的問題是,「我的登錄用戶沒有用戶名?

+2

我真正的問題是「即使我剛開始第一次調試,我的用戶如何登錄?」 – Ortund

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是一流的,基於當前上下文返回用戶ID(或任何獨特的用戶令牌)(即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; 
    } 
} 
+0

這是AntiForgeryConfig.SuppressIdentityHeuristicChecks(帶有「s」)。 – sprinter252

+0

@ sprinter252 - 良好的通話,固定。 –

+0

ContoscoHttpContext做什麼? – slolife