14

나는 이것에 대해 가능한 한 많은 답변을 읽었지만, 하나의 세부 사항에 미치지 못하는 것 같습니다.생성자 인수로 필터링 할 Ninject 바인딩 속성

문제는 (컨트롤러에 의해 서비스가 주입 된) 작업 필터를 해당 속성에 바인딩 할 때 속성에서 바인딩 된 필터로 매개 변수/속성 값을 전달하는 방법을 파악하지 못했습니다. 아래는 코드입니다, 내 목적으로 허위 코드 있음 아래 :

필터 & 특성

public class AuthorizationFilter : IAuthorizationFilter 
{ 
    private readonly IAuthorizationService _authorizationService; 
    private readonly UserRoles _requiredRoles; // Enum 

    public AuthorizationFilter(IAuthorizationService authorizationService, UserRoles requiredRoles) 
    { 
     _authorizationService = authorizationService; 
     _requiredRoles = requiredRoles; 
    } 

    public void OnAuthorization(AuthorizationContext filterContext) 
    { 
     if (filterContext.HttpContext.Session == null) 
      HandleUnauthorizedRequest(filterContext); 
     else { 
      var authorized = _authorizationService.IsUserInRole((UserSessionInfoViewModel) filterContext.HttpContext.Session["user"], _requiredRoles); 
      if (!authorized) 
       HandleUnauthorizedRequest(filterContext); 
      // else TODO: deal with cache... 
     } 
    } 
} 

public class RequireRolesAttribute : FilterAttribute 
{ 
    public readonly UserRoles RequiredRoles; 

    public RequireRolesAttribute(UserRoles requiredRoles) 
    { 
     RequiredRoles = requiredRoles; 
    }   
} 

필터/바인딩

kernel.BindFilter<AuthorizationFilter>(FilterScope.Controller, 0) 
     .WhenControllerHas<RequireRolesAttribute>(); 
kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0) 
     .WhenActionMethodHas<RequireRolesAttribute>(); 

속성이해야 확실히 어떤 컨트롤러/[RolesRequired]로 장식 된 액션은 필터에 바인딩됩니다. 여태까지는 그런대로 잘됐다. 이제는 속성을 통해 (많은 권한을 가진 AuthorizeAttribute와 같은) 역할을 선언하고 그 값을 실제로 권한 부여를 수행하는 필터로 전달하려고합니다.

의도/가짜 코드 : 특히

[RequireRoles(UserRoles.Author)] 
public ActionResult Index() 
{ 
    // blah 
} 

,이 역할의 AuthorizationFilter을 알려 걸립니까 무엇

? 필터/ninject가 속성의 생성자에 전달 된 인수에 액세스 할 수 있습니까? 필터/속성을 공용 속성에서 가져올 수 있습니까?

는 참고로,이 기사가 큰 도움이되었다,하지만 한 가지 대답하지 않습니다

Dependency Injection with Ninject and Filter attribute for asp.net mvc

Custom Authorization MVC 3 and Ninject IoC

가 가 BZ, 레모 GLOOR, 다른 사람이 ... 어떻게 달성 할 수

을 이?

답변

19

나는 그것을 알아 냈습니다 (Remo의 지시와 문서 덕분에).

컨트롤러 또는 작업 필터에 바인딩하는 경우 적절한 .WithConstructorArgument 확장명을 사용하십시오. 내 액션 필터를 결합 예를 들어 다음과 같습니다

kernel.BindFilter<AuthorizationFilter>(FilterScope.Action, 0) 
     .WhenActionMethodHas<RequireRolesAttribute>() 
     .WithConstructorArgumentFromActionAttribute<RequireRolesAttribute>("requiredRoles", o => o.RequiredRoles); 

나는 Func을 <> 서명을 이해하면 모든 것이 분명 해졌다.가장 좋은 방법 나는이 내 속성의 확장 유형 특정 할

  1. 이었다 처리하는 것으로

    .WithConstructorArgumentFromActionAttribute<TAttribute>() 
    
  2. 람다를 통해 콜백 개체 (사용자 속성)에서 값을 가져 오기 :

    ("argumentName", o => o.PropertyName) 
    
+1

바로 티켓, 환호 – redsquare

+0

어떤 아이디어 클래스에서 파생 경우 수행해야하는 것과 같은'FilterAttribute'는 어떻게 할 수있는 여러 매개 변수 (위의 예 여러 parametes와 생성자를 가지고있는 즉 RequireRoles 클래스)와 생성자가 매개 변수는'.WithConstructorArgumentFromActionAttribute ()'에 매핑됩니다. – Vipresh

+1

'BindFilter <>()'메서드를 사용할 수있게하려면,'Ninject.Web.Mvc.FilterBindingSyntax'에 대한 참조를 추가 할 수 있습니다. – bump

8

및 추가하는 것을 잊지 마세요 범위에 BindFilter 확장 방법을 가지고;

using Ninject.Web.Mvc.FilterBindingSyntax; 
+15

이것은 답변이 아니므로 솔루션 대답에 대한 의견으로 게시해야합니다. – angularsen

+0

이 링크가 질문에 대답 할 수 있지만 여기에 답변의 핵심 부분을 포함하고 참조 용 링크를 제공하는 것이 좋습니다. 링크 된 페이지가 변경되면 링크 전용 답변이 유효하지 않게 될 수 있습니다. - [리뷰에서] (리뷰/저품절 포스트/18739473) – diceler

관련 문제