2010-03-30 3 views
1

Я поддерживаю сайт ASP.NET MVC, где они делают свою собственную безопасность. Таким образом, они создали класс, полученный от AuthorizeAttribute. В OnAuthorization у них есть код отражения, который находит метод на основе имени action в RouteData.Найти метод, который будет выполняться в контроллере с использованием отражения

Проблема, которую я вижу, что если у вас есть несколько функций в контроллере, которые отличаются только AcceptVerb или параметров, это можно не авторизовать пользователя:

IList<MethodInfo> methods = filterContext.Controller.GetType().GetMethods().Where(i=>i.Name == action).ToList(); 

foreach (MethodInfo method in methods) 
{ 
    //get all of the controller security properties, and check for access: 
    object[] props = method.GetCustomAttributes(typeof(ControllerSecurity), false); 
    foreach (ControllerSecurity prop in props) 
    { 
     //does the user have access to this area/action? 
     authorized = security.ValidateUserForAction(prop.SecurityArea, prop.SecurityAction); 

     //if we are authorized by one ControllerSecurity, then we are good. 
     if (authorized) 
     { 
      break; 
     } 
    } 
} 

ControllerSecurity класс класс Атрибут используется для украшения наших действий контроллера и описания доступа к безопасности, необходимые для этой функции:

//User needs to have VIEW privileges to REPORTS area: 
[ControllerSecurity("REPORTS", "VIEW")] 
public ActionResult Index(){...} 

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

Я просмотрел объект AuthorizationContext и не могу найти все равно, чтобы надежно найти метод действия, который в конечном итоге будет вызван.

У кого-нибудь есть идеи?

+0

Поскольку атрибуты находятся в самих действиях, вы можете не просто перебирать все атрибуты действий, пока не найдете тот, на котором вы фактически работаете? –

+0

Но если у меня есть два действия «Index» в моем контроллере, каждый с разными параметрами, каждый из них может иметь разные атрибуты безопасности. (Наверное, это не произойдет на практике, но мне нравится, чтобы код безопасности был максимально плотным) – mlsteeves

+0

Дополнительная информация здесь: http://stackoverflow.com/questions/2168942/c-custom-attributes-how-to-get-the -member-type-to-which-an-attribute-was-appl –

ответ

0

Я думаю, что Mvc дает вам возможность получить доступ к определенному действию. Я не пробовал, но попробовать это ..

object[] props = filterContext.ActionDescriptor.GetCustomAttributes(typeof(ActionMethodSelectorAttribute), false); 
foreach (ActionMethodSelectorAttribute prop in props) 
{ 
     //does the user have access to this area/action? 
     authorized = security.ValidateUserForAction(prop.SecurityArea, prop.SecurityAction); 

     //if we are authorized by one ControllerSecurity, then we are good. 
     if (authorized) 
     { 
       break; 
     } 
} 

вещь, чтобы отметить это filterContext.ActionDescriptor, она существует в AuthorizationContext, который передается в в методе OnAuthorization.

Если это не поможет, вы можете использовать ActionNameSelectorAttribute в своем коде поиска действий. Код, который вы указали, не всегда будет работать. Возьмите случай, когда кто-то явно использует ActionName["MyAction"], чтобы определить действие вместо имени подразумеваемого метода.

+0

Объект 'AuthorizationContext' не имеет имени' Actiondescriptor'. (http://msdn.microsoft.com/en-us/library/system.identitymodel.policy.authorizationcontext_members.aspx) – mlsteeves

+0

Хороший вопрос о том, что кто-то явно использует 'ActionName [" MyAction "]'! – mlsteeves

+2

Это неправильный класс, который вы связали (неправильное пространство имен) ( http://msdn.microsoft.com/en-us/library/system.web.mvc.authorizationcontext_members(VS.100).aspx) – Jab

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