2017-01-03 2 views
0

사용자가 API 라우트에 액세스 할 수 있는지 테스트하기 위해 응용 프로그램에 대한 사용자 정의 권한 부여 클래스를 작성했습니다. 내가 테스트하고있는 사용자는이 클래스가 제거를 테스트하는 모든 권한을 가지고 있지만 API는 여전히 실행 중입니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?사용자 정의 AuthorizeAttribute가 실패해야하지만 API가 실행되어야합니다.

UserActionsDictionary에는 키로 된 테넌트 ID와 작업에 대한 문자열 목록이 있습니다.

using System.Linq; 
using System.Web; 
using System.Web.Mvc; 

namespace Application { 
    public class HasActionAttribute : AuthorizeAttribute { 

     public string Actions { get; set; } 
     protected override bool AuthorizeCore(HttpContextBase httpContext) { 
      UserCache userCache = HELPERS.GetCurrentUserCache(); 
      return userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect(Actions.Split(',').ToList()).Any(); 
     } 

     protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext) { 
      filterContext.Result = new HttpUnauthorizedResult("Action not allowed for the current user"); 
     } 
    } 
} 

컨트롤러에 있습니다. 나는 라우트 내에서 권한 부여를 실패하게 만드는 것이 무엇인지 테스트하고있다. 심지어 결코 그것을 작성해서는 안되지만, 중단 점을 가지고 테스트가 거짓으로 나오는 것을보고있다.

[Authorize] 
public class TestController : ApiController { 

    [Route("api/Test/TestRoute")] 
    [HttpGet] 
    [HasAction(Actions="Test Action")] 
    public dynamic Test(){ 
     UserCache userCache = HELPERS.GetCurrentUserCache(); 
     bool test = userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect("Test Action".Split(',').ToList()).Any(); 
     return test; 
    } 
} 

나는 SO에 대해 비슷한 주제에 여기에 질문을 많이 볼 수 있지만 아무도 내가 여기에이 문제를 해결하기 위해 보이지 않는다.

+0

잘못된 'AuthorizeAttribute'를 상속 받고있는 것처럼 보입니다. 'System.Web.Http'는 System.Web.Mvc가 아니라 WebAPI 컨트롤러이기 때문에 상속 받아야합니다. – haim770

+0

@ haim770 System.Web.Http에 재정의 할 필요가없는 것 같습니다. System.Web.Http에서 상속해야하는 경우 질문을 변경하여 내가 수행하려는 것을 어떻게 구현합니까? – Andrew

+0

그들은 실제로 다르지만'System.Web.Http.AuthroizeAttribute'에서 상속받을 때 정확한 결과를 얻을 수 있습니다. https://msdn.microsoft.com/en-us/library/system.web.http.authorizeattribute(v=vs.118).aspx 및 http://stackoverflow.com/questions/12629530/how-to- 비정상 요구 사항 – haim770

답변

0

haim770 대부분 질문의 의견에 내 문제를 대답, 그래서 유사한 다른 사람을 위해 여기에 전체 답을 놓을 게요 문제.

내가 상속 한 AuthorizeAttribute입니다. System.Web.Http이 아닌 System.Web.MVC에서 상속해야했습니다. 속성의 최종 코드는 다음과 같습니다.

using System.Collections.Generic; 
using System.Linq; 
using System.Net; 
using System.Net.Http; 
using System.Web.Http; 
using System.Web.Http.Controllers; 

namespace Application { 
    public class HasActionAttribute : AuthorizeAttribute { 

     public string Actions { get; set; } 
     public override void OnAuthorization(HttpActionContext actionContext) { 
      UserCache userCache = HELPERS.GetCurrentUserCache(); 
      List<string> actionsList = Actions.Split(',').Select(a=>a.Trim(' ')).ToList(); 
      if (!userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect(actionsList).Any()) { 
       HandleUnauthorizedRequest(actionContext); 
      } 
     } 

     protected override void HandleUnauthorizedRequest(HttpActionContext filterContext) { 
      filterContext.Response = new HttpResponseMessage(HttpStatusCode.Forbidden) { Content = new StringContent("Action not allowed for the current user") }; 
     } 
    } 
} 
0

나는 당신이 넣어 잊어 버린 거라고 생각 : ~/App_Start/FilterConfig.cs에서

GlobalFilters.Filters.Add(new HasActionAttribute()); 

합니다.

FilterConfig은 글로벌 필터를 관리하는 데 사용됩니다.

UPDATE :

그리고 널 매개 변수를 확인 할 방법을 변경 :

protected override bool AuthorizeCore(HttpContextBase httpContext) { 
    if(string.IsNullOrWhiteSpace(Actions)) 
    { 
     return true; 
    } 
    UserCache userCache = HELPERS.GetCurrentUserCache(); 
    return userCache.UserActionsDictionary[userCache.CurrentTenantID.ToString()].Intersect(Actions.Split(',').ToList()).Any(); 
} 
+0

null 인 경우 단순히 null을 확인하고 null이면 null @Andrew – Yaser

+0

이것은 isn ' 글로벌, 그것은 개별 경로에 있어야합니다. – Andrew

+0

정확하게이 필터가없는 사용자는 건너 뜁니다. – Yaser