Asp.net MVC4:授权在控制器和行动

如果我在控制器和操作上都有“授权”属性,哪一个会起作用? 或者两者都会生效?

你问:

如果我有控制器和动作的授权属性,哪一个会起作用? 都?

为了简单回答:两者。 效果是AND两个限制在一起。 我会解释下面的原因

细节

所以,你可以问这个问题有几个原因。

  1. 你想知道如何执行一个额外的约束与一个方法相比。 例如
    • 在控制器级别,强制angular色“用户”
    • 在操作级别,另外强制angular色“admin”的用户
  2. 您想要在操作级别replace控制器约束
  3. 您想要在操作级别删除控制器约束,并使该方法对匿名用户可用

你没有指定你的MVC版本,所以我会假设今天是最新的(MVC 4.5)。 但是,即使使用MVC 3,答案也不会改变。

[Anonymous]覆盖控制器[Authorize] (情况3)

案例3.我不需要覆盖(使用[AllowAnonymous] ),因为它已经被全部回答,并已经遍布整个networking 。 只要说[AllowAnonymous] :如果你在一个动作上指定了[AllowAnonymous] ,那么即使控制器上有[Authorize] ,这个动作也会被公开。

您也可以使用全局filter使整个网站受到授权,并且在您想要公开的less数操作或控制器上使用AllowAnonymous

[Authorize]是添加剂(情况1)

案例1很容易。 以下面的控制器为例:

 [Authorize(Roles="user")] public class HomeController : Controller { public ActionResult AllUsersIndex() { return View(); } [Authorize(Roles = "admin")] public ActionResult AdminUsersIndex() { return View(); } } 

默认情况下, [Authorize(Roles="user")]使控制器中的所有操作仅对“用户”angular色可用。 因此,要访问AllUsersIndex您必须处于“用户”angular色。 但是,要访问AdminUsersIndex您必须同时处于“用户”和“pipe理员”angular色。 例如:

  • UserName:Bob,Roles:user, 不能访问AdminUsersIndex ,但可以访问AllUsersIndex
  • 用户名:Jane,angular色:admin, 不能访问AdminUsersIndexAllUsersIndex
  • 用户名:蒂姆,angular色:用户和pipe理员, 可以访问AdminUsersIndexAllUsersIndex

这说明[Authorize]属性是可加的。 属性的Users属性也是如此,它可以与Roles组合使用,使其更具限制性。

这种行为是由于控制器和动作属性的工作方式。 这些属性链接在一起,然后应用于订单控制器然后执行。 如果第一个拒绝授权,那么控制权返回并且行为的属性不被调用。 如果第一个通过了授权,那么第二个也会被检查。 您可以通过指定Order (例如[Authorize(Roles = "user", Order = 2)] )来覆盖此顺序。

覆盖[Authorize] (情况2)

案例2更棘手。 回想一下,按照(Global then)Controller然后Action的顺序检查[Authorize]属性。 第一个检测到用户没有资格被授权的获胜,其他人不会被调用。

解决这个问题的一个方法是定义两个新的属性如下。 [OverrideAuthorize]除了[Authorize]之外别的什么也不做。 它的唯一目的是定义一个我们可以检查的types。 [DefaultAuthorize]允许我们检查在请求中被调用的Action是否用[OverrideAuthorize]装饰。 如果是的话,我们推迟行动授权检查,否则我们继续进行控制器级别检查。

 public class DefaultAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { var action = filterContext.ActionDescriptor; if (action.IsDefined(typeof(OverrideAuthorizeAttribute), true)) return; base.OnAuthorization(filterContext); } } public class OverrideAuthorizeAttribute : AuthorizeAttribute { public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); } } 

我们可以像这样使用它:

 [DefaultAuthorize(Roles="user")] public class HomeController : Controller { // Available to accounts in the "user" role public ActionResult AllUsersIndex() { return View(); } // Available only to accounts both in the "user" and "admin" role [Authorize(Roles = "admin")] public ActionResult AdminUsersIndex() { return View(); } // Available to accounts in the "superuser" role even if not in "user" role [OverrideAuthorize(Roles = "superuser")] public ActionResult SuperusersIndex() { return View(); } } 

在上面的示例中,具有“超级用户”angular色的帐户即使不具有“用户”angular色, SuperusersIndex也可用。

我想补充一些重写[授权](情况2)

OverrideAuthorizeAttribute和DefaultAuthorizeAttribute可以正常工作,但是我发现你也可以使用OverrideAuthorizationAttribute来覆盖在更高级别定义的授权filter。

 [Authorize(Roles="user")] public class HomeController : Controller { // Available to accounts in the "user" role public ActionResult AllUsersIndex() { return View(); } // Available only to accounts both in the "user" and "admin" role [Authorize(Roles = "admin")] public ActionResult AdminUsersIndex() { return View(); } // Available to accounts in the "superuser" role even if not in "user" role [OverrideAuthorization()] [Authorize(Roles = "superuser")] public ActionResult SuperusersIndex() { return View(); } } 

如果在控制器上使用它,则此控制器的所有方法都将生效。

 [Authorize] public class SomeController(){ // all actions are effected public ActionResult Action1 public ActionResult Action2 

如果你想防止这些行为之一,你可以使用这样的事情:

 [Authorize] public class SomeController(){ // all actions are effected public ActionResult Action1 public ActionResult Action2 [AllowAnonymous] public ActionResult Action3 // only this method is not effected... 
Interesting Posts