2024-02-20 19:53 编辑:xiaolin 点击: 次 A+
Util应用框架权限快速入门
本节将引导你运行Util权限管理模块,并对UI按钮和API操作进行访问控制.
拉取 Util.Platform.Single 项目代码.
git clone ' : '/view/routes/identity/module/edit'})export class ModuleEditComponent extends TreeEditComponentBase<ModuleViewModel> { /** * 查询参数 */ queryParam: ResourceQuery; /** * 应用程序标识 */ @Input() applicationId; /** * 应用程序名称 */ @Input() applicationName; /** * 初始化模块编辑页 * @param injector 注入器 */ constructor(injector: Injector) { super(injector); let param = this.util.dialog.getData<any>(); if (param) { this.applicationId = param.applicationId; this.applicationName = param.applicationName; } } /** * 初始化 */ ngOnInit() { super.ngOnInit(); this.model.applicationId = this.applicationId; this.queryParam = this.createQuery(); } /** * 创建模型 */ createModel() { let result = new ModuleViewModel(); result.enabled = true; return result; } /** * 创建查询参数 */ protected createQuery() { let result = new ResourceQuery(); result.applicationId = this.applicationId; return result; } /** * 获取基地址 */ protected getBaseUrl() { return "module"; } /** * 选择图标 */ selectIcon(icon) { this.model.icon = icon; }}最后,查看 Web Api 控制器的代码.
打开 Util.Platform.Api/Controllers/Identity/ModuleController.cs 文件,如下所示.

模块控制器从 NgZorroTreeControllerBase 基类继承,已经封装将树形数据转换成 Ng Zorro 树形组件需要的数据格式.
NgZorroTreeControllerBase 基类提供的 QueryAsync 方法用于为树形表格提供数据,TreeQueryAsync 方法为树形或下拉树形提供数据.
点击 模块资源 列表 资源设置 按钮,打开 操作资源 列表, 如下所示.

操作资源 列表是一个内嵌表格,为模块资源提供细粒度访问控制,比如控制页面上的按钮.
资源还有两种常见类型, 列 资源和 行集 资源.
列 资源用来控制显示的字段.
行集 资源用来控制不同角色显示不同的内容,俗称数据权限.
行集资源需要使用规约对象封装查询条件,并接入 Util 授权体系.
这两种资源尚未实现,待基础功能完善以后提供,如果你的项目对数据权限控制有需求,可以告知,我们将提前实现它.
点击 操作资源 创建 按钮,打开 创建操作权限 对话框.

操作名称输入框提示常用操作,可以从中选择,或手工输入.
资源最重要的属性是标识.
对于UI按钮的控制,可以使用有意义的标识, 比如 application.create, 表示创建应用程序.
资源的定义由开发人员根据控制粒度决定,除了在管理系统添加资源数据,还需要修改相应代码.
下面以 创建应用程序 操作为例,介绍控制 UI 按钮和 API 需要的步骤.
添加创建应用程序操作资源.数据迁移已经创建了该资源,标识为 application.create.
UI 按钮访问控制打开 Util.Platform.Ui.Identity/Pages/Routes/Identity/Application/Index.cshtml 文件,如下所示.

只需要把 application.create 操作资源标识设置到 acl 属性即可.
acl 属性是 Ng Alain 提供的访问控制指令 *aclIf, 已经将 acl 属性全局添加到 Util UI所有 TagHelper 标签.
Api 访问控制打开 Util.Platform.Api/Controllers/Identity/ApplicationController.cs 文件,代码简化如下.
/// <summary>/// 应用程序控制器/// </summary>[Acl( "application.view" )] public class ApplicationController : CrudControllerBase<ApplicationDto, ApplicationQuery> { /// <summary> /// 初始化应用程序控制器 /// </summary> /// <param name="service">应用程序服务</param> public ApplicationController( IApplicationService service ) : base( service ) { ApplicationService = service; } /// <summary>/// 应用程序服务/// </summary>protected IApplicationService ApplicationService { get; } /// <summary>/// 创建/// </summary>/// <param name="request">创建参数</param>[HttpPost] [Acl( "application.create" )] public new async Task<IActionResult> CreateAsync( ApplicationDto request ) { return await base.CreateAsync( request ); } }注意 ApplicationController 控制器上面的 [Acl( “application.view” )] 特性.
Asp.Net Core 自带了一个授权特性 [Authorize] ,它默认的行为是只要登录认证成功,就能进行任何操作.
Authorize 特性可以设置 Roles 属性, 设置硬编码的角色列表,这不太灵活.
Authorize 特性还能设置 Policy 自定义授权策略, 这是一种灵活的授权方式,但每个需要授权的API都要设置 Policy 很费力.
Util Acl 特性从 Authorize 继承,并封装了特定的授权策略.
与 Authorize 的 Roles 不同的是, Acl 并不设置角色,因为角色是动态的,可能随时增加减少,所以设置角色是一种不太靠谱的方法,只适合角色固定的项目.
Acl 特性设置的是资源标识, 资源标识是固定不变的,理解这一点是将权限从业务逻辑中剥离出来的关键.
application.view 是查看应用程序操作资源.
任何功能页面都需要查看权限,如果没有细粒度控制需求,对整个页面和API进行控制即可.
现在只要某个角色拥有 application.view 操作资源,他就能对控制器中所有方法进行访问.
当需要进行更加细粒度的控制时,只需要在某个控制器方法上添加 [Acl] 特性,并设置相应的资源标识即可.
CreateAsync 方法添加了 [Acl( “application.create” )] 特性,这说明只有拥有 application.create 资源的角色才能进行创建操作.
统一 UI 按钮与 API 操作的资源标识是权限设置的最佳实践.
另一种方法是UI按钮与API操作使用不同的资源标识,再将API资源绑定到UI按钮,这种方式更复杂且容易出错.
如果仅对 Web Api 进行访问控制, 可以使用API资源, 资源标识为 Api 地址,不需要在每个控制器打上 [Acl] 特性,Util 还提供了Acl过滤器,可以全局启用访问控制.
拥有细粒度操作资源的角色必须拥有查看资源.
对于本例,如果需要访问 CreateAsync 操作,Asp.Net Core首先验证 application.view 资源是否能访问,如果通过才会继续验证 application.create 资源.
授予权限一旦创建操作资源,并在 UI 和 API 进行了Acl设置,就可以为角色授权.
数据迁移默认创建了两个角色,admin 和 test,并已将用户 test 关联到 test 角色,以及将用户 admin 关联到 admin角色.
点击左侧 角色 菜单,打开角色列表.
角色列表中点击 test 角色 权限设置 链接,如下所示.

弹出 角色权限设置对话框,如下所示.

默认 test 角色只能查看应用程序.
下面来验证权限控制是否生效.
鼠标移到右上方头像,弹出菜单点击 退出登录 链接.

使用 test 用户登录,密码 test .
可以看到,只有一个应用程序菜单,并且操作按钮也消失了.

退出登录,使用 admin 用户登录.
打开 test 角色 权限设置 窗口,勾选 授予 应用程序 的 创建 复选框,点击确定按钮,如下所示.

还支持拒绝权限,如果用户的某个角色拥有拒绝资源,则无法访问该资源.
退出登录,使用 test 用户登录.
打开应用程序页面,可以看到创建按钮已经显示出来.

打开 Swagger ,之前已经测试过创建应用程序 API 接口无法访问,下面再来试试.

提交下面的数据.
{ "code": "test", "name": "test", "enabled": true}提交返回操作成功消息,说明权限设置生效.

一旦 Web Api 控制器添加了 [Acl] 特性,权限就已经启用.
对于某些场景可能相当麻烦,比如 Web Api 集成测试.
权限是由 Identity Server 提供的,你的集成测试需要从 Identity Server 获取令牌,这造成了不必要的负担.
Util应用框架支持全局关闭访问控制,如下所示.
.AddAcl( t => t.AllowAnonymous = true )AddAcl 配置 Util访问控制相关的服务依赖,AllowAnonymous让所有添加了 [Acl] 的方法跳过权限检测,无需登录,无需授权.