我已经阅读了有关使用IAuthorizatinService进行基于资源的授权的Microsoft文章,但是它只允许对一种资源进行自动授权。例如,我有一个User类和File类。文件具有所有者,可以是公共的,也可以不是公共的,因此,只有文件的公共或用户是此文件的所有者,才能查看文件。我需要显示不同用户的所有文件的列表,以便每个用户将看到所有公共文件和所有拥有的文件。在授权处理程序中,我有这个:
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);
}
}
但是它看起来很丑,因为我必须从DB加载所有文件,然后逐个过滤它们。如果我有数百万个文件,并且其中大多数不是用户也不属于公众,该怎么办?由于内存不足,我将无法全部加载它们并进行此类过滤。我可以将其重写为LINQ查询,然后让DB来完成所有工作:
var authorizedFiles = _dbContext.Files
.Select(f => f)
.Where(f.IsPublic || f.User.Identity?.Name == f.Owner)
.ToList();
但是然后我将在代码中有两个地方执行相同的操作,因此,每当我需要更改授权逻辑时,都必须修复代码的两个不同部分。那么正确的做法是什么?
不要使用自定义授权提供者过多的额外成本和复杂性。
有一个地方可以获取文件列表,并让数据库完成文件名过滤和排序的繁重工作。
因不得不了解ASP.NET框架数十个/数百个特殊功能而付出的代价减少了一千个。每个特殊知识项目每年花费几分钟的时间来为您和未来的开发人员提供支持,并增加了项目的风险。
结合在一起,需要成百上千个小的附加功能/专业知识,这将使保持生产系统正常运行并增强它的成本增加了工时(数月?)。微软似乎忘记了它的简单性,并在每个新版本的ASP.NET中不断添加许多专业知识所需的功能。
开发人员应该能够阅读应用程序主程序,然后跟踪整个应用程序代码库中的每一段代码是如何调用的,而无需了解ASP.NET框架的内部/可扩展性。”