如何在ASP.NET Core中创建自定义策略AuthorizeAttribute?

时间:2019-05-21 09:35:48

标签: c# asp.net-core authorization

我正在开发一个Intranet应用程序(通过AD登录),该应用程序需要按用户部门的授权权限,标题或AD中的其他信息。

在MS Docs中,看来我应该使用基于声明的授权(https://docs.microsoft.com/en-us/aspnet/core/security/authorization/claims?view=aspnetcore-2.2)。

您可以想象,某些页面应该由不同的部门授权,如链接所示,我可以做的是添加多个部门策略,但这很无聊,因为我有数十个部门。

我该怎么做才能实现这样的目标?

[Authorize(Policy = "Department" , Value = "Finance")]
[Authorize(Policy = "Title" , Value = "VP")]

谢谢。

2 个答案:

答案 0 :(得分:1)

您正在寻找policy-based authorization

策略由一个或多个要求组成,您可以通过实现IAuthorizationRequirement接口来定义。然后,您创建一个AuthorizationHandler<T>,并根据给定的要求验证当前上下文。在您的情况下,这可验证当前用户是否是[Authorization]属性中指定的必需部门的一部分。如果您需要更多控制权或拥有更具体的授权逻辑,则可以实施IAuthorizationHandler来一次处理多个需求。

我建议您看一下有关实施和注册策略及其要求和处理程序的文档。

答案 1 :(得分:0)

除了Henk所说的之外,您还可以使用基于外部策略的框架,例如。最终结果类似于Henk编写的内容,但是它基于策略而不是基于代码(使用IAuthorizationRequirement)。

政策看起来像普通的英语。

policyset documents{
    target clause objectType == "document"
    apply firstApplicable
    policy employees{
        target clause user.role == "employee"
        apply firstApplicable
        /**
         * Employees can create documents in their own company
         */
         rule createDocument{
             target clause action.actionId=="create"
             condition user.company==resource.company
             permit
         }
         /**
          * Employees can delete documents they own
          */
        rule allowDelete{
            target clause action.actionId == "delete"
            condition user.userId == resource.owner
            permit
        }
    }
}

然后,您需要将策略部署到授权引擎/策略决策点,然后从应用程序中的拦截器中调用它。这样可以使业务逻辑(应用程序)与授权逻辑(策略)分离。这也意味着您可以在各种应用程序中重复使用相同的策略/授权,无论使用哪种语言,也可以跨堆栈(API,应用程序,数据库...)