为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
波斯汪 2022-11-21 16:56:46
我正在寻找一种解决方案/建议来帮助我创建基于权限的对 Web API 端点/控制器操作的访问。基于角色的访问是不合适的,因为我没有可以在 Role("Admin") 或 Role("Controller") 等代码中使用的固定规则。基于声明的权限也不可行,因为每个用户/客户可以对每个业务对象/实体拥有不同的权限(例如,读取/写入访问自己的票证和读取访问他/她公司的所有票证,或者如果它是我的技术人员公司可以完全访问所有客户的所有票据。因此,每个用户都会有 10s 甚至数百个索赔,我必须在每次访问我的 API 时对其进行评估。这是数据库中的某种多租户,租户是我们的客户,拥有某种可以访问所有租户数据的“主租户”。我认为像 Visual Guard 这样的东西可以满足我的需求,但它非常昂贵,而且他们现在不支持 net core,而且他们的文档似乎已经过时了。我不需要立即找到可用的解决方案,但我会非常感谢一些提示和技巧,因为我现在正在寻找和搜索一些时间。关于“数据库权限”的详细信息: 我的意思是在我的前端(Winforms 应用程序)我想建立一个安全系统,我可以在其中创建角色并将其分配给用户,并且在这些角色中定义了用户可以执行哪些操作以及哪些 CRUD 操作他/她可以对特定的业务对象进行操作。每个角色可以有 n 个用户,每个角色可以有 n 个权限。每个权限本身声明为 exmaple Create:false、Read:true、Write:true 和 Delete:false。如果未找到特定业务对象的权限,则完全拒绝该 BO 上的 CRUD。因此,每当我的 API 中的一个操作被调用时,我必须检查该用户和他/她的规则是否允许他根据我的数据库中的规则和权限执行该特定操作。详细说明应用程序结构: 前端将是一个 Winforms 应用程序,它通过 OData 在后台调用 API。我不想完全依赖 Winforms 应用程序的安全性,因为 API 可以从互联网访问,我不能确定用户是否不会尝试使用他的凭据访问 api 只是为了看看没有什么是可能的“前端过滤器”。因此,权限位于 API 中,如果用户尝试在前端应用程序中访问 st,则应用程序本身会“询问”API 是否可行。稍后我想创建也使用 Odata Web API 的移动客户端。
查看完整描述

1 回答

?
森栏

TA贡献1810条经验 获得超5个赞

asp.net core中相关的API有:


授权服务

授权策略

授权要求

IAuthorizationHandler

您正在寻找的授权模式称为 Resource-based authorization


https://learn.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;

    }

}

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


查看完整回答
反对 回复 2022-11-21
  • 1 回答
  • 0 关注
  • 117 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信