如何在控制器和操作级别使用Authorize属性?

时间:2013-10-16 12:09:01

标签: c# asp.net-mvc security

我已经实现了自己的自定义授权属性。

该属性既适用于控制器级别,也适用于操作级别。

以下是我需要做的一个例子:

[ClaimsAuthorize(Roles = "AdvancedUsers")]
public class SecurityController : Controller
{
    [ClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdministrativeTask()
    {
        return View();
    }

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

目前,如果用户具有管理员角色但不具有AdvancedUsers角色,则他无法执行“管理任务”。

即使用户未获得控制器级别的授权,如何更改此行为以在操作级别执行安全检查?

目前,我能想到的唯一解决方案是实现2个属性:一个用于保护控制器,另一个用于保护操作。然后我将使用Order属性首先在动作级别执行一个。

但是,如果可能的话,我更倾向于使用单一属性的解决方案。

5 个答案:

答案 0 :(得分:2)

要限制特定操作,只需对处理这些操作的方法使用Authorize属性即可。 使用“授权”属性标记操作方法时,对该操作方法的访问仅限于经过身份验证和授权的用户。

     //[ClaimsAuthorize(Roles = "AdvancedUsers")]
     public class SecurityController : Controller
     {

        {
        [ClaimsAuthorize(Roles ="Administrators", "Role2","Role3")]
        public ActionResult AdministrativeTask()
        {
            return View();
        }
    }

或者您可以在控制器级别覆盖您的授权, 创建新的OverrideAuthorizeAttribute属性。

public class OverrideAuthorizeAttribute : AuthorizeAttribute {
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        base.OnAuthorization(filterContext);
    }
}

您可以使用此属性覆盖控制器级别的自动化。

[ClaimsAuthorize(Roles = "AdvancedUsers")]
public class SecurityController : Controller
{
    [ClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdministrativeTask()
    {
        return View();
    }
     [OverrideAuthorizeAttribute(Roles ="xxxx")] // This role will override controller                   
                                                  //level authorization 
    public ActionResult SomeOtherAction()
    {
        return View();
    }
}

答案 1 :(得分:2)

这不应该是可能的。想象一下MVC使用授权过滤器的逻辑。

  1. 确定控制器后 - 检查是否有适用于该控制器的授权过滤器并执行它。
  2. 当操作已知时 - 对操作执行相同操作。
  3. 在所有情况下,授权失败都会使管道短路。

答案 2 :(得分:2)

使用内置[OverrideAuthorization()]

[ClaimsAuthorize(Roles = "AdvancedUsers")]
public class SecurityController : Controller
{
    [OverrideAuthorization()]
    [ClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdministrativeTask()
    {
        return View();
    }

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

答案 3 :(得分:1)

您需要两个授权属性 - 一个具有所有授权逻辑的基本属性,另一个派生自base属性的属性,仅用于覆盖基本属性。

授权属性示例:

public class ClaimsAuthorizeAttribute : AuthorizeAttribute
{
    protected bool _canOverride = true;

    //...custom authorization code goes here.....

    public override void OnAuthorization(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        //Don't authorize if the override attribute exists
        if (_canOverride && actionContext.ActionDescriptor.GetCustomAttributes<OverrideClaimsAuthorizeAttribute>().Any())
        {
            return;
        }
        base.OnAuthorization(actionContext);
    }

}


public class OverrideClaimsAuthorizeAttribute : ClaimsAuthorizeAttribute
    {
        public OverrideClaimsAuthorizeAttribute ()
            : base()
        {
            _canOverride = false;
        }

    }

在基本授权属性中,只要OverrideClaimsAuthorizeAttribute不存在,我们就会继续正常授权。如果OverrideClaimsAuthorizeAttribute确实存在,那么只对_canOverride为false的类(即OverrideClaimsAuthorizeAttribute类本身)运行授权。

使用示例:

[ClaimsAuthorize(Roles = "AdvancedUsers")]
public class SecurityController : Controller
{

    //Ignores the controller authorization and authorizes with Roles=Administrators
    [OverrideClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdministrativeTask()
    {
        return View();
    }


    //Runs both the controller and action authorization, so authorizes with Roles=Administrators AND Roles=AdvancedUsers
    [ClaimsAuthorize(Roles = "Administrators")]
    public ActionResult AdvancedAdministrativeTask()
    {
        return View();
    }

    //authorizes with controller authorization: Roles=AdvancedUsers
    public ActionResult SomeOtherAction()
    {
        return View();
    }
}

答案 4 :(得分:0)

检查this上一个问题。 (查看@AndyBrown回答,案例2)

对于一种简单的方法,您也可以尝试添加(     [AllowAnonymous])覆盖控制器     [授权] 然后添加一个新的自定义过滤器以检查此特定操作的逻辑。或者您可以添加检查其中的角色的代码。