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

发布于 2024-08-27 02:15:46 字数 1355 浏览 8 评论 0原文

我正在维护一个 ASP.NET MVC 站点,他们在那里做自己的安全工作。因此,他们创建了一个从 AuthorizeAttribute 派生的类。在OnAuthorization中,它们有一些反射代码,可以根据RouteData中的action名称查找方法。

我看到的问题是,如果控制器中有多个操作函数,仅 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 class 是一个 Attribute 类,用于装饰我们的控制器操作,并描述该功能所需的安全访问:

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

必须有更好的方法来做到这一点,而无需重写安全性。我想确定地知道我们只检查最终将运行的方法。

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

有人有什么想法吗?

I'm maintaining an ASP.NET MVC site where they are doing their own security. So they have created a class derived from AuthorizeAttribute. In the OnAuthorization, they have some reflection code that finds the method based on the action name in RouteData.

The problem that I see, is that if you have multiple action functions in the controller, that differ by only AcceptVerb, or parameters, it will possible not authorize the user:

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

The ControllerSecurity class is an Attribute class used to decorate our controller actions, and describe the security access required for this function:

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

There must be a better way of doing this, without rewriting the security. I would like to know with some certainty that we only check the method that will be eventually run.

I've looked through the AuthorizationContext object, and can't find anyway to reliably find the action method that will be eventually called.

Anyone have any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千年*琉璃梦 2024-09-03 02:15:46

我认为 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"] 来定义操作而不是隐含方法名称的情况为例。

I think Mvc gives you a way to access the particular action already. I haven't tried it but try this..

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

The thing to note is filterContext.ActionDescriptor, it exists in the AuthorizationContext that is passed in in the OnAuthorization method.

If that doesn't work, you might look into using ActionNameSelectorAttribute in your action finding code. The code you showed won't always work. Take the case of someone explicitly using ActionName["MyAction"] to define the action instead of the implied method name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文