我正在试图查看任何可能在MVC 3应用程序中的控制器中修饰操作方法的身份验证属性。我在我自己的HtmlHelper扩展方法中执行此操作,这些方法基本上是ActionLink的包装器(为您提供我在运行时可用的信息的上下文)。我有一个基本的解决方案,但重载方法刚刚爆炸。我知道框架在内部解析了动作方法的URL,但在查看了System.Web.Mvc.LinkExtensions的代码之后,我仍然没有准确地发现它是如何发生的,所以我有点陷入困境解决这个问题。
以下是我目前解决相关方法的代码:
private static bool _IsUserAuthorized(HtmlHelper html,
string controllerName, string actionName)
{
controllerName = controllerName ??
html.ViewContext.RouteData.GetRequiredString("controller");
var factory = ControllerBuilder.Current.GetControllerFactory();
var controller = factory.CreateController(
html.ViewContext.RequestContext, controllerName);
Type controllerType = controller.GetType();
var methodInfo = controllerType.GetMethod(actionName,
BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
... check authentication
}
所以我当前的问题是,当一个方法被覆盖时,我会得到“模糊匹配”异常。我猜我需要处理RouteValues来解析方法的任何参数,这样我才能明确地识别正确的参数。有没有人对如何做到这一点有一些指示?或者,框架是否已经提供了解决所需方法的手段?
非常感谢!
答案 0 :(得分:2)
编辑:更新了方法以包含来自this page的见解。最终版本查看AuthorizationFilters以获取所请求的操作方法,并检查用户是否有权执行操作。
所以我在System.Web.Mvc.ControllerActionInvoker中挖掘并找到了我需要的方法和构造函数。 ControllerDescriptor.FindAction()最终成为关键。下面,我复制了我写的方法检索所有属性
private static bool _IsUserAuthorized(HtmlHelper htmlHelper,
string controllerName, string actionName)
{
ControllerContext controllerContext = null;
//if controllerName is null or empty, we'll use the
// current controller in HtmlHelper.ViewContext.
if (string.IsNullOrEmpty(controllerName))
{
controllerContext = htmlHelper.ViewContext.Controller.ControllerContext;
}
else //use the controller factory to get the requested controller
{
var factory = ControllerBuilder.Current.GetControllerFactory();
ControllerBase controller = (ControllerBase)factory.CreateController(
htmlHelper.ViewContext.RequestContext, controllerName);
controllerContext = new ControllerContext(
htmlHelper.ViewContext.RequestContext, controller);
}
Type controllerType = controllerContext.Controller.GetType();
ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType);
ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName);
if (actionDescriptor == null)
return false;
FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(
controllerContext, actionDescriptor));
AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor);
foreach (IAuthorizationFilter authFilter in filters.AuthorizationFilters)
{
authFilter.OnAuthorization(authContext);
if (authContext.Result != null)
return false;
}
return true;
}
答案 1 :(得分:0)
添加授权码的常用方法是使用Authorization Filter。
IAuthorizationFilter.OnAuthorization提供AuthorizationContext对象,该对象具有ActionDescriptor
属性。