8

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

该属性适用于控制器级别和操作级别。

这是我需要做的一个例子:

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

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

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

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

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

但是,如果可能的话,我更喜欢具有单个属性的解决方案。

4

5 回答 5

8

使用内置[OverrideAuthorization]

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

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

OverrideAuthorization属性可用于 MVC 5(至少)及更高版本。一旦你Action用它装饰,也用新的装饰,这将在关卡角色上Role生效。Controller

于 2017-02-21T06:09:43.827 回答
2

To make specific actions restricted you simply use the Authorize-attribute on the methods that handle these actions. When you mark an action method with the Authorize attribute, access to that action method is restricted to users who are both authenticated and authorized.

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

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

OR you can override your authorization at controller level , Create a new OverrideAuthorizeAttribute attribute.

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

and you can use this attribute to override your controller level autorization.

[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();
    }
}
于 2013-10-16T12:41:35.837 回答
2

This should not be possible. Imagine the logic which MVC uses with the authorization filters.

  1. When the controller is determined - check if there is an authorization filter that applies to that controller and execute it.
  2. When the action is known - do the same for the action.

In all cases a fail in authorization would short-circuit the pipeline.

于 2013-10-16T13:48:33.373 回答
1

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

授权属性示例:

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();
    }
}
于 2013-12-21T17:37:51.523 回答
0

检查这个先前的问题。(检查@AndyBrown 答案,案例 2)

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

于 2013-10-16T12:57:05.653 回答