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

时间:2014-11-01 13:10:42

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

这是我的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 在执行特定操作时总是得到 null

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

UPDATE1:

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

2 个答案:

答案 0 :(得分: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 :(得分:1)

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

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

这是一个例子。

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