【问题标题】:Custom authorise attribute not overriding/combining on specific actions自定义授权属性不覆盖/组合特定操作
【发布时间】:2017-09-20 15:42:35
【问题描述】:

我创建了一个自定义授权属性,以允许一些自定义检查来确定整个应用程序的访问权限。

在控制器级别应用自定义身份验证属性,然后尝试添加对特定操作的额外访问权限时,角色不会以“附加”方式应用。

自定义授权属性:

// Allow multiple = true so should roll all occurrences in a request into one
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)]
public class CustomAuthoriseAttribute : AuthorizeAttribute
{
    public CustomAuthoriseAttribute(params string[] roles)
    {
        this.Roles = string.Join(",", roles);
    }

    /// <summary>
    /// Custom routines to determine if a request is considered authorised.
    /// </summary>
    /// <param name="httpContext"></param>
    /// <returns></returns>
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        if (httpContext == null)
        {
            throw new ArgumentNullException("httpContext");
        }

        var userManager = httpContext.GetOwinContext().GetUserManager<UserManager>();

        var user = userManager.FindById(httpContext.User.Identity.GetUserId());

        if (user == null)
        {
            return false;
        }

        // Log the user out as they should not be allowed access
        if (user.IsDisabled || user.IsDeleted)
        {
            httpContext.GetOwinContext().Authentication.SignOut(DefaultAuthenticationTypes.ApplicationCookie);
            httpContext.Session.Clear();

            return false;
        }

        return base.AuthorizeCore(httpContext);
    }
}

在控制器中的使用:

似乎正在对 SuperAdmin 和 Admin 进行身份验证检查,然后自行对顾问进行检查,这会导致未经授权的请求。为什么他们没有得到完全治疗?

[CustomAuthorise(SuperAdministrator, Administrator)]
public class SomeController : Controller
{
    public const string SuperAdministrator = "SuperAdministrator";
    public const string Administrator = "Administrator";
    public const string Consultant = "Consultant";

    // Should only accessible by SuperAdministrators and Administrators
    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }

    // Should be accessible by SuperAdministrators, Administrators and Consultants
    [HttpGet]
    [CustomAuthorise(Consultant)]
    public ActionResult SomeAction()
    {
        return View();
    }
}

【问题讨论】:

  • 您是否调试过代码并检查自定义属性中返回 false 的位置?
  • 它在调用 base.AuthorizeCore(httpContext) 时返回 false,这意味着在执行 user.IsInRole 检查 Roles 属性中的任何项目时它必须失败,在这种情况下不包含 ALL指定的角色。
  • 您是否尝试在调用基本方法之前检查代码中的user.IsInRole 以确保这是问题所在?
  • 是的,刚刚检查过,第一个命中(对于超级管理员和管理员)返回 true,然后第二个命中(对于顾问)返回 false。注意:我正在使用管理员用户进行测试。由于我设置了AllowMultiple = true,它不应该将它们视为一次实例吗?
  • AllowMultiple = true 用于属性使用,而不是用于更改底层逻辑。因此,如果用户没有顾问角色,它将不会授权用户。 AlloMultiple 对此无能为力。

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


【解决方案1】:

使用逻辑 AND 处理多个授权属性。每个属性的结果都与前一个进行“与”运算。在这种情况下,SomeAction 只能由超级管理员或管理员(基于控制器级别属性)和顾问(基于操作级别属性)访问。

有几种不同的方法可以做到这一点,但我建议不要在控制器级别授予顾问访问权限,因为您会将特权帐户(超级管理员和管理员)与受限帐户(顾问)混合。

我将创建一个可供所有三个角色访问的新控制器,并将此操作移到那里。然后您可以将您的特权方法留在原始控制器中。

[CustomAuthorise(SuperAdministrator, Administrator)]
public class PrivilegedController : Controller
{

    // Should only accessible by SuperAdministrators and Administrators
    [HttpGet]
    public ActionResult Index()
    {
        return View();
    }

}

[CustomAuthorise(SuperAdministrator, Administrator, Consultant)]
public class LessPrivilegedController : Controller
{

    [HttpGet]
    public ActionResult SomeAction()
    {
        return View();
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 2014-10-28
    • 2016-05-14
    相关资源
    最近更新 更多