【问题标题】:How override the global AuthorizeAttribute when add same AuthorizeAttribute for some Action MVC?为某些 Action MVC 添加相同的 AuthorizeAttribute 时如何覆盖全局 AuthorizeAttribute?
【发布时间】:2014-11-01 13:10:42
【问题描述】:

这是我的 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());
}

对于某些特定的操作,我使用参数 ControllerName 添加它:

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

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

那是因为我不能将全局 authorizeAttribute 和相同的 Attibute 用于某些特定的操作 together??为什么?我一直认为如果我为特定的Action添加一些AuthorizeAttribute,并将Attribute添加到全局过滤器中,那么特定的Action就会得到高度优先级

更新1:

如果问题源是 2 授权全部执行。那么当我为某些操作添加相同的 AuthorizeAttribute 时,如何覆盖全局授权过滤器? (唯一不同的是参数,我只是希望它在我为某些操作添加一个时忽略全局授权)

【问题讨论】:

  • 您可以手动更改该属性的 Order 属性,使其首先被触发。

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


【解决方案1】:

我通过结合 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
...

【讨论】:

    【解决方案2】:

    更改自定义属性的 Order 属性,使其首先被触发:

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

    这是一个示例课程。

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

    【讨论】:

    • 谢谢。但是我可以将顺序设置为全局过滤器吗?那么我不需要为每个特定的操作设置顺序。
    • 可以,在默认构造函数中设置一个默认值,并创建一个自定义值的重载构造函数
    • 我正在注册全局过滤器使用filters.Add(new AdminAuthorizeAttribute(), 1); 看起来订单最小编号是高度优先,请编辑您的答案。但现在的问题是:它不会覆盖全局过滤器,2个过滤器都会执行.....
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多