2012-10-09 5 views
10

나는 다음과 같은 코드를 넣어있을 때 : 유형의안티 위조 시스템 MVC

제공되는 정체성 다음

@Html.AntiForgeryToken() 

부분은 다음과 같은 예외가 thrownig입니다

@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로 표시되지만 Name에는 값이 없습니다. 기본적으로 위조 방지 시스템에서는 인증 된 모든 ID에 고유 한 이름이 필요합니다. 이 ID에 대해 고유 한 이름을 제공 할 수없는 경우 정적 속성 AntiForgeryConfig.AdditionalDataProvider를 현재 사용자에 대한 고유 한 식별자 형식을 제공 할 수있는 유형의 인스턴스로 설정하십시오.

많은 예제를 확인하고 웹 검색을 시도했지만 설명을 찾을 수 없습니다. 이 오류가 왜 나에게 일어 났는지 알고 싶습니다. 그리고 그것을 위장 방지법을 사용하여 해결하는 방법.

답변

6

로그인 했음에도 불구하고 Membership.GetUser().UserName에 해싱에 사용할 수있는 이름이 없으므로 작동하지 않는다고 말합니다.

그래서 당신의 진짜 문제는, "올 어떻게 내 사용자 이름이없는 로그인 한 사용자?"

+2

내 실제 문제는 "방금 처음 디버깅을 시작 했는데도 내 사용자가 어떻게 로그인합니까?"입니다. – Ortund

6

로그인 한 사용자가 Identity.Name을 설정하지 않은 경우가 있습니다 (제 경우에는 내 앱을 일부 미친 시스템에 통합해야합니다). 그런 다음 두 가지 방법이 주위에있다 :

1) 비보안 - 모든 사용자가 자신의 인증 상태에 관계없이 antiforgery 시스템에 의해 같은 방식으로 처리됩니다

// System.Web.WebPages.dll 
using System.Web.Helpers; 

// not a production solution 
public class MvcApplication : HttpApplication { 
    protected void Application_Start() { 
    AntiForgeryConfig.SuppressIdentityHeuristicChecks = true; 
    } 
} 

2) 보안 - 자신의 (정의) 방식으로 방법을 제공 당신은 당신의 사용자를 구별 ContoscoHttpContext가 현재 컨텍스트를 기반으로 사용자 ID (또는 고유 한 사용자 토큰을)를 돌려줍니다 (즉 HttpContextBase)입니다

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; 
    } 
} 
+0

AntiForgeryConfig.SuppressIdentityHeuristicChecks ("s"포함)입니다. – sprinter252

+0

@ sprinter252 - 좋은 전화. –

+0

ContoscoHttpContext는 어떤 기능을합니까? – slolife