首页 文章

如何为某些 Action MVC 添加相同的 AuthorizeAttribute 时如何覆盖全局 AuthorizeAttribute?

提问于
浏览
2

这是我的 CustomAuthorizeAttribute 类:

public class CustomAuthorizeAttribute : AuthorizeAttribute
{

       public string ControllerName { get; set; }

      public override void OnAuthorization(AuthorizationContext filterContext)
      {
           if (ControllerName != "pass")
           {
            // stop or redirect
           }

      }
}

我将它注册到全局过滤器,所有控制器都可以使用:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
      filters.Add(new AdminAuthorizeAttribute());
}

对于某些特定的 Action,我将它与 param ControllerName一起添加:

[AdminAuthorize(ControllerName="pass")]
public ActionResult Index()
{
      return View();
}

但问题是现在在OnAuthorization()中,ControllerName在执行特定 Action 时总是得到null

是因为我不能使用全局 authorizeAttribute 和同一个 Attibute 一起用于某些特定的动作****为什么?我一直认为如果我为特定 Action 添加一些 AuthorizeAttribute,并将 Attribute 添加到全局过滤器,则特定 Action 将获得height priority

UPDATE1:

如果问题源是 2 授权全部执行。那么当我为某些 Action 添加相同的 AuthorizeAttribute 时,我如何覆盖全局授权过滤器? (只有不同的是 param,我只是想在我为一些 Action 添加一个时忽略全局授权)

2 回答

  • 2

    我使用 Order 属性和请求已通过我的属性授权的上下文项中的标记的组合来完成此操作:

    public class AuthorizeByRolesAttribute : AuthorizeAttribute
    {
        private const string AuthorizedContextItemName = "_AuthorizedByRoles";
    
        public AuthorizeByRolesAttribute (params string[] roles)
        {
            this.Order = 0;
            this.Roles = string.Join (",", roles);
        }
    
        public override void OnAuthorization (AuthorizationContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Items[AuthorizedContextItemName] != null)
                return;
    
            base.OnAuthorization (filterContext);
    
            filterContext.RequestContext.HttpContext.Items[AuthorizedContextItemName] = this.Roles ?? string.Empty;
        }
    }
    

    在全球配置中:

    filters.Add (new AuthorizeByRolesAttribute ("Admin"), 255);
    

    在控制器中简单:

    [AuthorizeByRoles ("NotAdminButCanAccess")]
    public class MyController : Controller
    ...
    
  • 1

    在自定义属性上更改为 Order 属性,以便首先触发它:

    [AdminAuthorize(ControllerName="pass", Order=999)]
    public ActionResult Index()
    {
          return View();
    }
    

    这是一个例子。

    是的,您可以通过这种方式覆盖全局过滤器。

相关问题