asp.net-core - ASP.NET Core 自定义授权
问题描述
我需要在 .NET 5 API 上实现基于角色的授权,但问题是我们不想用属性和角色列表来装饰所有控制器,因为所有这些配置都来自配置文件 (JSON)或外部服务(待定),以将角色映射到控制器和操作的方式,我们希望有一些东西可以集中所有这些逻辑,就像我们之前使用身份验证过滤器和属性所做的那样。
我一直在阅读,现在来自 MS 的想法是一切都通过策略和要求来处理,但我不知道如何将所有这些都融入我们想要的架构中。最重要的是因为我看不到(或看不到)我如何访问 Controller 和 Action 的描述符以了解我在执行授权过程时所处的位置。
有没有办法在这个新模型上实现这一点?
编辑:我找到了一种获取控制器和操作描述符的方法,以便完成我想要的部分操作。根据我阅读的其他一些问题和文章以及我自己的一些修补,我得到了以下信息:
public class AuthorizationFilter : IAsyncAuthorizationFilter
{
public Task OnAuthorizationAsync(AuthorizationFilterContext context)
{
var descriptor = (ControllerActionDescriptor)context.ActionDescriptor; //<<-- this is the key casting :)
var ctrlName = descriptor.ControllerName;
var actionName = descriptor.ActionName;
var userPrincipal = context.HttpContext.User;
//DO STUFF AND DECIDE RESULT TYPE BASED ON USER CLAIMS AND CURRENT CONTROLLER AND ACTION
context.Result = new ForbidResult();
context.Result = new UnauthorizedResult();
return Task.CompletedTask;
}
}
然后我可以通过以下方式添加此过滤器:
services.AddControllers(x => x.Filters.Add<AuthorizationFilter>());
IAuthorizationRequirement
这样我可以用 ASP.NET MVC 4/5 实现与以前类似的东西,但据我所知,.NET Core 团队试图通过实现and机制来替代所有这些,从而摆脱这条道路AuthorizationHandler<T>
,所以我怀疑仍然:这是在新的 .NET Core 3.x / .NET 5 架构中执行此操作的正确方法吗?或者我是否有其他方式忽略了如何获取和处理正在执行的控制器/动作并将其传递给一个AuthorizationHandler
?
解决方案
您正在寻找的是所谓的外部授权,也称为基于属性的访问控制。在这个模型中:
- 授权逻辑与应用程序解耦
- 授权逻辑表示为建立在属性之上的策略
- 属性是描述主题、操作、资源和正在发生的事情的上下文的键值对(用户希望在给定时间和地点对对象执行操作)
- 授权是根据逻辑中心点中的这些策略决定的(逻辑是因为出于性能原因,您很可能将该中心点的多个实例与您的应用程序共存)。ABAC中的逻辑中心点称为策略决策点 (PDP)
- 授权是根据您要执行的地方的 PDP 的响应执行的。这可以在方法级别,也可以在 API 级别,甚至是 UI 级别:您可以选择。负责执行决策的组件称为策略执行点 (PEP)。
有一个称为xacml的主要标准及其对开发人员友好的表示法称为alfa,可让您实现基于属性的访问控制。值得注意的是,这种模型和方法适用于任何应用程序(根本不是 .NET 特定的)。
推荐阅读
- python - Python递归函数(扁平化(数据))
- html - 顶部导航栏项目背景不覆盖整个空间,它只覆盖文本
- duplicates - Redshift 删除重复记录但保持最新
- node.js - 使用 NestJs 连接到 SQL Server
- mongodb - MongoDB:写关注 w:[number>1] - 为什么?
- node.js - Kinesis Lambda 源转换:数据属性未经过 base64 编码
- python - 使用 Pygame 在 Python 游戏中随机显示图像
- c# - 我可以在 Winform/C# 应用程序中显示 Excel 文件并保持格式吗?
- php - 将一串数字转换为浮点数时..为什么我只得到第一个数字?
- go - 三个 etcd-go 包有什么区别?