Asp.net MVC4:授权在控制器和行动
如果我在控制器和操作上都有“授权”属性,哪一个会起作用? 或者两者都会生效?
你问:
如果我有控制器和动作的授权属性,哪一个会起作用? 都?
为了简单回答:两者。 效果是AND
两个限制在一起。 我会解释下面的原因
细节
所以,你可以问这个问题有几个原因。
- 你想知道如何执行一个额外的约束与一个方法相比。 例如
- 在控制器级别,强制angular色“用户”
- 在操作级别,另外强制angular色“admin”的用户
- 您想要在操作级别replace控制器约束
- 您想要在操作级别删除控制器约束,并使该方法对匿名用户可用
你没有指定你的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, 不能访问
AdminUsersIndex
或AllUsersIndex
- 用户名:蒂姆,angular色:用户和pipe理员, 可以访问
AdminUsersIndex
和AllUsersIndex
这说明[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...