2013-05-07 5 views
3

내 컨트롤러의 메서드에 대한 기본 액세스를 설정하려고하므로 ApiController[Authorize] 특성을 추가했습니다.컨트롤러 수준의 기본 권한 부여 역할

[AllowAnonymous] 속성으로 덮어 쓰지 않는 한 대부분 잘 작동합니다.

이제 다른 레벨을 믹스에 추가하고 싶습니다. 기본적으로 권한이 부여 된 메소드의 경우, 컨트롤러 레벨 속성을 [Authorize(roles="admin")]으로 업데이트하기 위해 관리자와 같은 특정 역할을 요구해야합니다. 몇 가지 예외는 있지만, 나는 그들이 어떤 역할을하고 있는지 상관하지 않는다. (단지 인증만으로 충분하다.)

컨트롤러 수준에서 Authorize 특성을 설정하고 개별 메서드 수준에서 재정의 할 수 있다고 생각했지만이 방법은 [AllowAnonymous]과 동일하게 작동하지 않습니다.

기본 액세스 수준으로 모든 새 메소드를 꾸미는 것을 기억하지 않고도이를 수행하는 방법에 대한 제안이 있습니까? [Authorize(roles="*")]과 같은 것? 의 모든 사용자가이라는 기본 역할을 수행해야하는 경우에도 AuthenticatedUsers과 같은 부분은 괜찮습니다.

답변

7

마커 속성을 만드는 방법은 어떻습니까? AllowAnonymous는 그러한 마커 중 하나입니다 (BTW). 자신의 Authorize 속성을 만들고 마커가있을 때 역할을 지 웁니다.

[MyAuth(Roles = "admin")] 
public class ValuesController : ApiController 
{ 
    [ExemptRoles] 
    public IEnumerable<string> Get() 
    { 
     return new string[] { "value1", "value2" }; 
    } 
} 

public class ExemptRolesAttribute : Attribute { } 

public class MyAuthAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     if (actionContext.ActionDescriptor.GetCustomAttributes<ExemptRolesAttribute>().Any()) 
      base.Roles = String.Empty; 

     base.OnAuthorization(actionContext); 
    } 
} 
+0

좋은 해결책. 감사! – earthling

1

기본적으로 내가하는 일입니다. 사용자 정의 AuthorizeAttribute을 작성하고 OnAuthorization 메소드를 대체했습니다.

그러면 사용자가 현재 사용자 지정 속성에 태그 지정된 역할 중 하나인지 확인할 수 있습니다.
그렇지 않은 경우 기본 승인 처리로 되돌아갑니다.

public class InternalAuthorizeAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext) 
    { 
     if(actionContext == null) 
      throw new ArgumentNullException("actionContext"); 
     if (AuthorizeRequest(actionContext)) 
      return; 

     // no special authorization found. fall back to base (handles AllowAnonymous, and Controller level attribute) 
     base.OnAuthorization(actionContext); 
    } 


    private bool AuthorizeRequest(HttpActionContext actionContext) 
    { 
     if (!actionContext.ActionDescriptor.GetCustomAttributes<InternalAuthorizeAttribute>().Any()) 
      return false; 

     foreach (AuthorizeAttribute attribute in actionContext.ActionDescriptor.GetCustomAttributes<AuthorizeAttribute>()) 
     { 
      foreach (var role in attribute.Roles.Split(',')) 
      { 
       if (HttpContext.Current.User.IsInRole(role)) return true; 
      } 
     } 
     return false; 
    } 
} 
관련 문제