具有控制器继承的基于角色的授权

时间:2018-08-27 07:44:38

标签: asp.net-core asp.net-authorization

我正在使用ASP.NET Core 2.1

我有一个抽象的控制器基类,它具有CRUD操作的基本实现。我们希望将其中大多数限制为仅对某些用户(例如具有Admin角色的用户)可调用,而允许某些用户或其他角色使用。

它会以这种方式工作吗?

[Authorize(Roles = "Admin")]
abstract class BaseController<T> : Controller
{
    public virtual IActionResult GetAll() { }
    public virtual IActionResult Create(T entity) { }
    public virtual IActionResult Read(int id) { }
    public virtual IActionResult Delete(int key) { }
}

[Authorize(Roles = "ClassRole")]
class EntityController : BaseController<Entity>
{
    [AllowAnonymous]
    public override IActionResult GetAll() { } //callable by anyone?

    //Create not overriden so callable only by Admins (and/or ClassRole?)

    public override IActionResult Read() //overridden but no attribute so ClassRole?

    [Authorize(Roles = "MehodRole")]
    public override IActionResult Delete() { } //all 3 (Admin, ClassRole, MethodRole) or something?
}

如果基类中还存在其他Authorize属性,并且一个属性中有多个角色,则只会变得疯狂。

谢谢

2 个答案:

答案 0 :(得分:0)

如果您正在使用身份,就可以轻松实现,但是如果要自定义角色身份验证,则可以查看本文https://docs.microsoft.com/tr-tr/aspnet/core/mvc/controllers/filters?view=aspnetcore-2.1

答案 1 :(得分:0)

编辑:正如OP所暗示的,我误解了他的问题。

如果您不想使用多个授权属性,则必须使用自定义策略。您可以找到示例here。然后,您可以在策略中使用一个授权属性。

[Authorize(Policy = "MyRoleRequirementPolicy")]

在该策略中,您检查所需的角色。您可以拥有比身份验证更大的逻辑。在启动代码中,您只需添加类似的策略

services.AddAuthorization(options =>
{
    options.AddPolicy("MyRoleRequirementPolicy", policy =>
        policy.Requirements.Add(new CheckRolesPolicy(role1, role2, role3))); // you can register them with multiple roles under different names as often as you want
});

始终可以在基本实现中使用此行为。如果您将其他属性添加到派生的控制器或特定的端点,则基本行为将被忽略。

在这种情况下,为什么我认为继承不是一个好主意:

  1. 对于任何事情,您永远都不会拥有相同的端点。
  2. 您不应将实体传递给控制器​​,控制器完全不应了解任何有关实体的知识,并且您将希望拥有具有不同属性的不同模型类型,以使其更加灵活并传输较小的数据,例如在创建模型时新实体或仅修补现有实体的某些字段
  3. 您应该引入类似休息的行为,以便进行描述,以防某些第三方开发人员会在某些时候使用您的api。当然,您仍然可以通过路由说明来做到这一点
  4. 继承并不总是正确的事情,尤其是在这里并非如此。这样可以隐藏细节。其他一些开发人员可能会在您不需要授权时复制您的代码。有些事情应该是显性的而不是隐性的。找到两者之间的平衡有时不是最容易的任务。

这只是我的意见。您的工作完全取决于您:)

上一个答案:我不建议使用带有Authorize属性的基本控制器。 无论如何,您可以在一个函数上拥有多个授权属性

[Authorize(Roles = "Admin")]
[Authorize(Roles = "ClassRole")]
[Authorize(Roles = "MehodRole")]
public override IActionResult Delete() { }