【发布时间】:2020-04-03 15:39:54
【问题描述】:
我已阅读有关使用 IAuthorizatinService 进行基于资源的授权的 Microsoft 文章,但它只允许对一个资源进行自动化。例如我有一个用户类和文件类。文件有一个所有者,可以是公共的,也可以不是公共的,因此只有当文件是公共的或用户是该文件的所有者时,才能查看该文件。我需要为不同用户显示所有文件的列表,这样每个用户都会看到所有公共文件和所有拥有的文件。 在授权处理程序中我有这个:
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context,
OwnerOrPublicRequirement requirement,
File resource)
{
if (resource.IsPublic || context.User.Identity?.Name == resource.Owner)
{
context.Succeed(requirement);
}
return Task.CompletedTask;
}
然后在控制器中我必须这样做:
List<File> authorizedFiles = new List<File>();
foreach (var file in _dbContext.Files)
{
var result = await _authorizationService
.AuthorizeAsync(User, file, new OwnerOrPublicRequirement());
if (result.Success)
{
authorizedFiles.Add(file);
}
}
但它看起来很难看,因为我必须从数据库加载所有文件,然后一一过滤它们。如果我有数以百万计的文件,并且其中大多数不是公共的,也不归用户所有,该怎么办?由于内存不足,我将无法加载所有这些并像这样过滤。我可以将其重写为 LINQ 查询,让 DB 完成所有工作:
var authorizedFiles = _dbContext.Files
.Select(f => f)
.Where(f.IsPublic || f.User.Identity?.Name == f.Owner)
.ToList();
但是我将有两个地方的代码做同样的事情,所以每当我需要更改授权逻辑时,我必须修复两个不同的代码部分。那么这样做的正确方法是什么?
【问题讨论】:
标签: c# asp.net-core authorization