权限 快速入门
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 角色只能查看应用程序.
验证操作权限
下面来验证权限控制是否生效.
验证 UI 按钮权限
鼠标移到右上方头像,弹出菜单点击 退出登录 链接.
使用 test 用户登录,密码 test .
可以看到,只有一个应用程序菜单,并且操作按钮也消失了.
为 test 角色授予创建权限
退出登录,使用 admin 用户登录.
打开 test 角色 权限设置 窗口,勾选 授予 应用程序 的 创建 复选框,点击确定按钮,如下所示.
还支持拒绝权限,如果用户的某个角色拥有拒绝资源,则无法访问该资源.
退出登录,使用 test 用户登录.
打开应用程序页面,可以看到创建按钮已经显示出来.
验证 Api 权限
打开 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] 的方法跳过权限检测,无需登录,无需授权.