Asp.net mvc 使用反射查找将在控制器中执行的方法

Asp.net mvc 使用反射查找将在控制器中执行的方法,asp.net-mvc,asp.net-mvc-routing,Asp.net Mvc,Asp.net Mvc Routing,我正在维护一个ASP.NETMVC站点,他们在那里做自己的安全性工作。因此,他们创建了一个派生自AuthorizeAttribute的类。在OnAuthorization中,他们有一些反射代码,根据RouteData中的操作名称查找方法 我看到的问题是,如果控制器中有多个操作函数,它们之间的差异仅为AcceptVerb或参数,则可能无法授权用户: IList<MethodInfo> methods = filterContext.Controller.GetType().GetMet

我正在维护一个ASP.NETMVC站点,他们在那里做自己的安全性工作。因此,他们创建了一个派生自
AuthorizeAttribute
的类。在
OnAuthorization
中,他们有一些反射代码,根据
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;
        }
    }
}
必须有更好的方法来实现这一点,而不必重写安全性。我想确定地知道,我们只检查最终将运行的方法

我已经查看了
AuthorizationContext
对象,但无论如何都找不到可靠的方法来找到最终将被调用的操作方法


有人有什么想法吗?

我认为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,它存在于通过
OnAuthorization
方法传入的AuthorizationContext中


如果这不起作用,您可以研究在操作查找代码中使用
ActionNameSelectorAttribute
。你显示的代码并不总是有效的。例如,有人明确使用
ActionName[“MyAction”]
来定义操作,而不是隐含的方法名称。

因为属性在操作本身上,你能不能不迭代所有的actions属性,直到找到你实际操作的那一个?但是如果我的控制器中有两个
Index
操作,每个操作都有不同的参数,它们可能都有不同的安全属性。(在实践中可能不会发生,但我希望安全代码尽可能紧凑)这里有更多信息:我不确定我是否理解为什么您需要知道正在执行哪个控制器方法。我正在做一件非常类似的事情,我不需要知道控制器的方法就可以让它工作。如果security属性未授权,它会缩短控制器方法的执行(发生重定向)。@robert-假设您有两个索引操作,一个具有检查视图访问的安全描述符,而另一个检查编辑访问。如果首先选中具有VIEW属性的方法,则上述代码可能会授予访问权限,即使其他索引是要激发的。最终结果是,只允许具有查看权限的用户查看仅针对具有编辑权限的用户的内容。--顺便说一句,我真的不喜欢这个应用程序的安全性,因为它完全是定制的,没有利用已经存在的东西。但是我们现在被束缚住了。
AuthorizationContext
对象没有成员
Actiondescriptor
。()关于某人显式使用
ActionName[“MyAction”]
的案例,这是一个很好的观点!这是您链接的错误类(错误的名称空间)()虽然我最初的链接是错误的,但我仍然没有在IntelliSense中看到
ActionDescriptor
。。我想我正在使用的是:AuthorizationContext.ActionDescriptor由于疏忽而被意外地遗漏在MVC 1中。它出现在MVC2中。
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;
        }
}