ASP.NET核心Web API:基于数据库权限的授权

时间:2019-03-31 14:31:12

标签: c# asp.net-core-webapi

我正在寻找一种解决方案/建议,以帮助我创建对Web api端点/控制器操作的基于权限的访问。

基于角色的访问不适合,因为我没有可以在诸如Role(“ Admin”)或Role(“ Controller”)之类的代码中使用的固定规则。

基于权利要求的权限也是不可行的,因为每个用户/客户可以对每个业务对象/实体具有不同的权限(例如,对自己的票证具有读/写访问权限,对公司的所有票证具有读权限,或者我公司的技术人员可以完全访问所有客户的所有票证,因此每个用户将有10甚至什至数百个索赔,我必须在每次访问API时对其进行评估。

这只是数据库中的一种多租户,并且租户是我们的客户,具有某种“主租户”,可以访问所有租户数据。

我认为像Visual Guard这样的东西可以满足我的需求,但是它非常昂贵,并且它们目前不支持网络核心,并且其文档似乎已经过时了。

我不需要立即可用的解决方案,但是由于我正在寻找并寻找一些时间,因此我将非常感激如何实现该目标的一些提示和技巧。

“数据库权限”的详细信息: 我的意思是在我的前端(Winforms应用程序)中,我想建立一个安全系统,在该系统中可以创建用户并向用户分配角色,并在这些角色中定义了用户可以执行的操作以及他/她可以对特定对象执行的CRUD操作业务对象。每个角色可以具有n个用户,每个角色可以具有n个权限。每个权限本身都声明了例如Create:false,Read:true,Write:true和Delete:false。如果未找到对特定业务对象的许可,则会完全拒绝该BO上的CRUD。

因此,每当调用我的API中的操作时,我都必须检查该用户及其规则是否允许他根据数据库中的规则和权限执行该特定操作。

详细说明应用程序结构: 前端将是一个Winforms应用程序,它将由OData在后台调用API。我不想完全依赖Winforms应用程序中的安全性,因为可以从Internet上访问该API,而且我不确定用户是否不会尝试使用其凭据访问api,只是为了看看possblie是什么。 “前端过滤器”。因此,权限位于API中,并且如果用户尝试访问s.t。如果可能的话,在前端应用程序中,应用程序本身会“询问” API。 稍后,我想创建也使用Odata Web API的移动客户端。

1 个答案:

答案 0 :(得分:2)

asp.net核心中的相关API是:

  • IAuthorizationService
  • AuthorizationPolicy
  • IAuhtorizationRequirement
  • IAuthorizationHandler

您正在寻找的授权模式称为基于资源的授权

https://docs.microsoft.com/en-us/aspnet/core/security/authorization/resourcebased?view=aspnetcore-2.2

基本上,您可以定义AuthorizationPolicy,并将其应用于资源实例:

var ticket = _ticketRepository.Find(ticketID);

var authorizationResult = await _authorizationService
        .AuthorizeAsync(User, ticket, "EditTicketPolicy");

在授权处理程序中,您可以检查用户是否是资源的所有者。

public class ResourceOwnerRequirement : IAuthorizationRequirement
{
}

public class ResourceOwnerHandler 
    : AuthorizationHandler<ResourceOwnerRequirement, MyBusinessObject>
    //: AuthorizationHandler<ResourceOwnerRequirement> use this overload to handle all types of resources...
{
    protected override Task HandleRequirementAsync(
        AuthorizationHandlerContext context, 
        ResourceOwnerRequirement requirement, 
        MyBusinessObject resource)
    {
        int createdByUserId = resource.CreatedBy;
        Claim userIdClaim = ((ClaimsIdentity)context.User.Identity).FindFirst("UserId");

        if (int.TryParse(userIdClaim.Value, out int userId)
            && createdByUserId == userId)
        {
            context.Succeed(requirement);
        }
    }
}

//admin can do anything
public class AdminRequirementHandler : IAuthorizationHandler
{
    public Task HandleAsync(AuthorizationHandlerContext context)
    {
        if (context.User.Claims.Any(c => c.Type == "Role" && c.Value == "Administator"))
        {
            while (context.PendingRequirements.Any())
            {
                context.Succeed(context.PendingRequirements.First());
            }
        }
        return Task.CompletedTask;
    }
}

顺便说一句,这仍然可以称为声明或基于角色的授权。具有特定角色的用户可以编辑自己的票证,但是具有管理员角色的用户也可以编辑其他票证。区别在于您将授权应用于资源,而不仅仅是操作

编辑: