Найдите метод, который будет выполнен в контроллере, используя отражение - PullRequest
1 голос
/ 30 марта 2010

Я поддерживаю сайт 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 - это класс Attribute, используемый для оформления действий нашего контроллера и описания безопасного доступа, необходимого для этой функции:

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

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

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

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

1 Ответ

0 голосов
/ 30 марта 2010

Я думаю, что 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"] для определения действия вместо подразумеваемого имени метода.

...