使用反射查找将在控制器中执行的方法
我正在维护一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我认为 Mvc 已经为您提供了一种访问特定操作的方法。我还没有尝试过,但试试这个..
需要注意的是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..
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 usingActionName["MyAction"]
to define the action instead of the implied method name.