2017-01-03 2 views
0

Я создал специальный класс атрибутов авторизации для своего приложения, чтобы проверить, разрешен ли пользователю доступ к маршруту API. Пользователь, с которым я тестирую, имел все разрешения, которые этот класс будет тестировать для удаления, однако api все еще работает. Что я делаю не так?Пользовательский авторизованный атрибут должен быть неудачным, но API работает

UserActionsDictionary имеет идентификаторы арендаторов в качестве ключей и список строк для действий.

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

Я вижу здесь много вопросов по поводу подобных тем, но ни один из них не рассматривает проблему, которую я здесь.

+0

Похоже, вы наследуете неправильный 'AuthorizeAttribute'. Вам нужно наследовать от 'System.Web.Http' не' System.Web.Mvc' (поскольку это контроллер WebAPI). – haim770

+0

@ haim770 System.Web.Http, похоже, не имеет того, что мне нужно переопределить. если мне нужно наследовать от System.Web.Http, это меняет вопрос на то, как я реализую то, что я пытаюсь сделать? – Andrew

+0

Они разные, но вы можете добиться точного результата при наследовании от 'System.Web.Http.AutroizeAttribute'. См. Https://msdn.microsoft.com/en-us/library/system.web.http.authorizeattribute(v=vs.118).aspx и http://stackoverflow.com/questions/12629530/how-to- customize-asp-net-web-api-authorizeattribute для необычных требований – 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

Я думаю, что ты забыла поставить:

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

в ~/App_Start/FilterConfig.cs.

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

Просто проверить нуль и передать истину, если она равна нулю – Yaser

+0

Это @ Андрей ISN' глобальный, он должен находиться на отдельных маршрутах. – Andrew

+0

Точно это означает, что вы должны пропустить тех, у кого нет этого фильтра – Yaser

Смежные вопросы