ASP.NET MVC 4控制器类和方法上的自定义授权过滤器

时间:2018-09-28 19:31:53

标签: asp.net-mvc-4 c#-3.0 authorize-attribute

我确实看到了这个stackoverflowQuestion,但这与使用Authorize属性有关。我通过扩展AuthorizeAttribute使用自定义授权属性。

我希望能够将此自定义过滤器放置在控制器类的顶层,但是对于两种方法,它们仅强制执行特定角色,而不同时强制顶层和动作方法角色。

所以

[AuthorizeUser("Transact")]
public class HomeController : Controller
{
    //
    // GET: /Search/Home/

    public ActionResult Index()
    { 
        return View();
    }

    [AuthorizeUser("Search")]
    public ActionResult Search()
    { 
        return View();
    }

}

这样做,框架将检查用户是否同时具有事务处理和搜索角色。在这种情况下,我只想检查搜索角色。

我正在另一个区域重用此搜索功能和局部视图。

2 个答案:

答案 0 :(得分:1)

回到我发布的链接:stackoverflowQuestion我可以使它在我的情况下起作用。似乎正在发生的事情是,对我的操作的调用首先从Controller级别查看了该属性,但是在OnAuthroization方法中使用filterContext.ActionDescriptor.IsDefined将告诉我被调用的操作是否附加了我的override属性。如果这样做,它将跳过对base.OnAuthorization方法的调用,然后将调用override属性。

因此,我要做的是创建重写类并扩展我的自定义授权类。我在父对象中声明了一个标志,并在覆盖类的构造函数中进行了设置,以告诉我覆盖授权方法是否正在调用我的自定义授权类的授权方法。

以下是使这一切有意义的示例。

public class AuthorizeUserAttribute : AuthorizeAttribute
{
    protected bool isOverrideAuthorize = false;

    public AuthorizeUserAttribute(params...)
    {
    }

    public AuthorizeUserAttribute(MenuItems...)
    {
    }

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var action = filterContext.ActionDescriptor;
        if (action.IsDefined(typeof(OverrideAuthorizeUserAttribute), true) && !isOverrideAuthorize)
        {
            return;
        }

        base.OnAuthorization(filterContext);
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {

    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
    }
  }

覆盖类:

public class OverrideAuthorizeUserAttribute : AuthorizeUserAttribute
{
    public OverrideAuthorizeUserAttribute(params...) : base(roles)
    {
        base.isOverrideAuthorize = true;
    }

    public OverrideAuthorizeUserAttribute(MenuItems...) : base(item)
    {
        base.isOverrideAuthorize = true;
    }

    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        return base.AuthorizeCore(httpContext);
    }
}

这使我可以仅对该动作声明的授权属性执行该动作的授权,而不是框架默认的控制器AND动作方法的授权属性。

此外,MVC5似乎通过包含“ OverrideAuthorization”属性来解决此问题。不幸的是,我仍然使用MVC4。

答案 1 :(得分:0)

您可以像下面这样尝试在控制器的顶部,这将支持单个控制器的多个角色,或者您可以在每个操作的顶部使用相同的Authorize(Roles =“ Admin”)过滤器。...

[Authorize(Roles = "Admin,HRManager,Finance")]
Public class MyController:Controller{

  // inside controller action methods
 }