我正在寻找一个解决方案/建议,帮助我创建基于权限的Web api端点/控制器操作访问。
基于角色的访问不适合,因为我没有可以在角色(“管理员”)命令角色(“控制器”)等代码中使用的固定规则。
基于声明的权限也是不可行的,因为每个用户/客户端可以对每个业务对象/实体具有不同的权限(例如,对自己的票证的读/写访问权限以及对他/她公司的所有票证的读取访问权限,或者如果它是我的技术人员公司可以完全访问所有客户的所有门票。因此,每次访问我的API时,每个用户都会有10个甚至是几个索赔。
它只是在数据库上的某种多租户,租户是我们的客户,有一些“主租户”可以访问所有租户数据。
我认为像Visual Guard这样的东西可以满足我的需求,但它相当昂贵,而且现在它们不支持网络核心,而且它们的文档似乎已经过时了。
我不需要立刻使用一个可用的解决方案,但是我可以实现的一些提示和技巧将非常适用,因为我现在正在寻找并寻找一些时间。
有关“数据库权限”的详细信息:我的意思是在我的前端(Winforms应用程序)我想建立一个安全系统,我可以在其中创建并为用户分配角色,并在这些角色中定义用户可以执行哪些操作以及哪些CRUD操作他/她可以对特定的业务对象进行操作。每个角色可以有n个用户,每个角色可以拥有n个权限。自己的每个权限都声明为exmaple Create:false,读取:true,Write:true和Delete:false。如果未找到特定业务对象的权限,则完全拒绝该BO上的CRUD。
因此,无论何时调用我的API中的操作,我都必须检查该用户及其规则是否允许他根据我的数据库中的规则和权限执行该特定操作。
详细说明应用程序结构:前端将是一个Winforms应用程序,它由OData在后台调用API。我不想完全依赖Winforms应用程序中的安全性,因为API可以从互联网访问,我不能确定用户是否不会尝试使用他的凭据访问api只是为了看看有什么可能没有“前端过滤器”。因此,权限位于API中,如果用户尝试访问s.t.在前端应用程序中,应用程序本身“询问”API是否可行。后来我想创建也使用Odata Web API的移动客户端。
asp.net核心中的相关API是:
您要查找的授权模式称为基于资源的授权
基本上,您可以定义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;
}
}
顺便说一句,这仍然可以称为声明或基于角色的授权。具有特定角色的用户可以编辑自己的票证,但具有admin角色的用户也可以编辑其他票证。不同之处在于您将授权应用于资源,而不仅仅是操作
编辑: