2009-12-21 4 views

답변

22

예. 당신은 Mvc 컨트롤러를 상속받은 자신의 BaseController를 생성하고 OnAuthorization()을 오버로드함으로써이를 수행 할 수 있습니다. 당신은 그것을 적용하기 전에이 POST 이벤트입니다 있는지 확인하려면 :

public abstract class MyBaseController : Controller 
{ 
    protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
    //enforce anti-forgery stuff for HttpVerbs.Post 
    if (String.Compare(filterContext.HttpContext.Request.HttpMethod, 
      System.Net.WebRequestMethods.Http.Post, true) == 0) 
    { 
     var forgery = new ValidateAntiForgeryTokenAttribute(); 
     forgery.OnAuthorization(filterContext); 
    } 
    base.OnAuthorization(filterContext); 
    } 
} 

당신은 확실히 모든 컨트롤러가 (당신이 전화 또는 무엇이든)이 MyBaseController에서 상속 만드는 것이 일단. 또는 동일한 코드를 원할 경우 각 컨트롤러에서이 작업을 수행 할 수 있습니다.

+1

이 해결 방법은 MVC2에서 작동하지 않습니다. MVC1에서는 정상적으로 작동하지만 v2로 업그레이드하자마자 작동이 멈췄습니다.지금 해결책을 찾고 있습니다. –

+0

제 관심을 가져 주셔서 감사합니다. 나는 또한 조사 할 것이다. – eduncan911

+1

적어도 _a_ 솔루션을 찾지 못했습니다. 아래 내 대답을 참조하십시오. 코멘트 박스는 코드 포맷 = = –

8

"당신이 그 버그를 놓는 것을 잊었습니다."방지하려는 소리가납니다. 그렇다면이 작업을 수행하는 가장 좋은 장소는 사용자 정의 ControllerActionInvoker입니다. , 컨트롤러에서 다음

public class MustHaveAntiForgeryActionInvoker : ControllerActionInvoker 
{ 
    protected override ActionDescriptor FindAction(ControllerContext controllerContext, ControllerDescriptor controllerDescriptor, string actionName) 
    { 
     var foundAction = base.FindAction(controllerContext, controllerDescriptor, actionName); 

     if(foundAction.GetCustomAttributes(typeof(ValidateAntiForgeryTokenAttribute), true).Length == 0) 
      throw new InvalidOperationException("Can't find a secure action method to execute"); 

     return foundAction; 
    } 
} 

바람직베이스 컨트롤러 :

ActionInvoker = new MustHaveAntiForgeryActionInvoker(); 

그냥 싶었

은 기본적으로 당신이하고 싶은 심지어 AntiForgery 토큰없이 작업을 찾는에서 MVC를 중지입니다 그 커스텀 Controller베이스 클래스를 추가하는 것은 "두꺼운"경향이 있으며, MVC의 훌륭한 확장 성 포인트를 사용하여 그들이 속한 곳에서 필요한 기능을 연결하는 것이 항상 최선의 방법입니다. 당신이 AuthorizeAttribute에 사용하는 경우 http://codeclimber.net.nz/archive/2009/04/08/13-asp.net-mvc-extensibility-points-you-have-to-know.aspx

7

좋아, 난 그냥 여기 MVC 2.0로 프로젝트 업그레이드 및 eduncan911의 솔루션은 더 이상 작동하지 않습니다 여기에

는 MVC의 확장 점의 가장 좋은 가이드 귀하의 컨트롤러 작업. 이유를 알아내는 것은 다소 어려웠습니다.

MVC 팀이 RequestVerificationToken의 값에 ViewContext.HttpContext.User.Identity.Name 속성을 사용했다는 이야기의 주범입니다.

기본 컨트롤러에서 덮어 쓰기 된 OnAuthorization은 컨트롤러 동작의 모든 필터보다 먼저 실행됩니다. 따라서 문제는 Authorize 특성이 아직 호출되지 않았으므로 ViewContext.HttpContext.User이 설정되지 않았기 때문입니다. 따라서 UserName은 String.Empty이지만 유효성 검사에 사용되는 AntiForgeryToken에는 실제 사용자 이름 = 실패가 포함됩니다.

우리는이 코드를 지금 해결 :

public abstract class MyBaseController : Controller 
{ 
    protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     //enforce anti-forgery stuff for HttpVerbs.Post 
     if (String.Compare(filterContext.HttpContext.Request.HttpMethod, "post", true) == 0) 
     { 
      var authorize = new AuthorizeAttribute(); 
      authorize.OnAuthorization(filterContext); 
      if (filterContext.Result != null) // Short circuit validation 
       return; 
      var forgery = new ValidateAntiForgeryTokenAttribute(); 
      forgery.OnAuthorization(filterContext); 
     } 
     base.OnAuthorization(filterContext); 
    } 
} 

MVC의 코드베이스에 일부 참조 :

ControllerActionInvoker#InvokeAuthorizationFilters() 라인 283 같은 단락. AntiForgeryData#GetUsername() 98 행. 새로운 기능.

+0

나는 앞으로 나아가고 나중에 upvotes (+3, 와우!) 준. 그러나 3.5 프레임 워크에서 VS2010 RTM과 함께 MVC 2.0 RTM을 사용하고 있습니다 (Azure 프로젝트이므로 지금은 3.5로 유지해야합니다). 내가 게시 한 위조 방지 해결책은 여전히 ​​작동합니다. 문제는 당신이 MVC 2.0 RC2 또는 비슷하게 사용했다는 것이 궁금해? – eduncan911

0

어때?

[ValidateAntiForgeryToken] 
public class MyBaseController : Controller 
{ 
} 
관련 문제