以编程方式获取ASP MVC Web应用程序的所有全局筛选器

时间:2019-04-26 21:08:19

标签: c# asp.net asp.net-mvc

我正在研究一个映射所有ASP MVC路由以创建菜单结构的代码段,到目前为止,我已经找到了不错的代码段,这些代码段使我可以检索ActionResults及其属性的列表。

作为最后一项要求,我想验证ActionResult是否需要身份验证。因为我可以验证控制器或操作本身是否具有Authorized属性,所以已经解决了这种情况,但是当我在全局范围内注册Authorization属性时,则无法解决。

是否可以注册所有全局过滤器?

这是到目前为止我的代码段的代码:

public static class MvcApplicationHelpers
{
    public static List<MvcApplicationRoute> MapMvcApplicationRoutes(Type mvcApplicationType, ApplicationActionReturnTypeNames applicationActionReturnType = ApplicationActionReturnTypeNames.ActionResult)
    {
        var mvcAssembly = Assembly.GetAssembly(mvcApplicationType);

        var assemblyProjectName = mvcAssembly.FullName.Split(',')[0];

        return mvcAssembly.GetTypes()
            .SelectMany(x => x.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
            .Where(x => x.ReturnType.Name == applicationActionReturnType.ToString())
            .Select(x => new MvcApplicationRoute
            {
                Controller = x.DeclaringType.Name.Replace("Controller", ""),
                Action = x.Name,
                ReturnTypeName = x.ReturnType.Name,
                Area = x.DeclaringType.Namespace.ReplaceMany(assemblyProjectName,"Area",".Controllers","Controllers"),
                Attributes = string.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", ""))),
                ControllerAttributes = string.Join(",", x.DeclaringType.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", ""))),
            })
            .ToList();
    }

    public static List<MvcApplicationNavigationRoute> MapMvcApplicationNavigationRoutes(Type mvcApplicationType, ApplicationActionReturnTypeNames applicationActionReturnType = ApplicationActionReturnTypeNames.ActionResult)
    {
        var mvcApplicationRoutes = MapMvcApplicationRoutes(mvcApplicationType, applicationActionReturnType);

        return mvcApplicationRoutes
            .Where(c => c.ReturnTypeName == ApplicationActionReturnTypeNames.ActionResult.ToString())
            .GroupBy(c => new
            {
                c.Action,
                c.Area,
                c.Controller,
                c.ControllerAttributes,
                c.Attributes
            })
            .Select(c => new MvcApplicationNavigationRoute
            {
                Action = c.Key.Action,
                Area = c.Key.Area,
                Controller = c.Key.Controller,
                RequiresAuthorization = ValidateAuthorizationRequiredAttributes(c.Key.Attributes, c.Key.ControllerAttributes),
            })
            .ToList();

    }

    private static bool ValidateAuthorizationRequiredAttributes(string attributes, string controllerAttributes)
    {
        string authorizedAttributeName = "Authorize";
        if(attributes.Contains(authorizedAttributeName) || controllerAttributes.Contains(authorizedAttributeName))
        {
            return true;
        }
        return false;
    }
}

public enum ApplicationActionReturnTypeNames
{
    ActionResult,
    PartialViewResult,
    FileResult
}

public class MvcApplicationRoute
{
    public string Area { get; set; }
    public string Controller { get; set; }
    public string Action { get; set; }
    public string Method { get; set; }
    public string ReturnTypeName { get; set; }
    public string Attributes { get; set; }
    public string ControllerAttributes { get; set; }
}

public class MvcApplicationNavigationRoute
{
    public string Area { get; set; }
    public string Controller { get; set; }
    public string Action { get; set; }
    public bool RequiresAuthorization { get; set; }
    public bool RequiresPermission { get; set; }
    public string[] AllowedRoles { get; set; }
    public string NavigationName { get; set; }
    public bool SpecialAccess { get; set; }
    public string Permission { get; set; }
    public string PermissionAction { get; set; }
}

1 个答案:

答案 0 :(得分:0)

  

作为最后一项要求,我想验证ActionResult是否需要   身份验证。

我不确定我是否了解您的要求,但是您的工作对我来说似乎是不标准的。

如果您全局添加了[Authorize]属性,则默认情况下,所有操作方法都将被授权。如果您不想授权某些操作方法,请向其中添加[AllowAnonymous]

public class MyController : Controller
{
    // Since you have globally registered [Authorize], this would be automatically Authorized
    public ActionResult MyAction()
    {
        // some code... 
    }

    [AllowAnonymous] // <-- do not authorize this action
    public ActionResult NoAuthorizeAction()
    {
        // some code... 
    }
}

验证是完全不同的事情,它通常在模型上完成...您可以向模型添加内置的验证属性,例如[Required][Range] ...您可以定义自己的Custom Validation Attribute,或者您的模型可以实现IValidatableObject。所有这些验证都将在您的模型上执行,您可以在控制器中检查模型状态是否有效...

我不确定为什么要验证“授权”属性?