我正在维护一个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
对象,无论如何都无法找到最终会被调用的动作方法。
有人有什么想法吗?
答案 0 :(得分: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 ,它存在于OnAuthorization
方法中传入的AuthorizationContext中。
如果这不起作用,您可以考虑在动作查找代码中使用ActionNameSelectorAttribute
。您展示的代码并不总是有效。以某人明确使用ActionName["MyAction"]
来定义操作而不是隐含的方法名称为例。