首页 > 代码库 > ABP官方文档翻译 4.4 授权
ABP官方文档翻译 4.4 授权
授权
- 介绍
- 关于IPermissionChecker
- 定义权限
- 检查权限
- 使用AbpAuthorize特性
- AbpAuthorize特性注意点
- 抑制授权
- 使用IPermissionChecker
- 在Razor视图
- 客户端(Javascript)
- 使用AbpAuthorize特性
- 权限管理
介绍
几乎所有的企业应用都在一定程度上使用授权。在应用中,授权用来检查用户是否允许执行一些特定的操作。ABP定义了一个基础的权限设施来实现授权。
关于IPermissionChecker
授权系统使用IPermissionChecker来检查权限。你可以使用自己的方式实现它时,但它已经在modul-zero工程里完全实现了。NullPermissionChecker用来将所有的权限赋给所有的人。
定义权限
每一个需要授权的操作都需要定义一个唯一的权限。我们应该先定义权限再使用。ABP设计为模块的。所以,不同的模块可以有不同的权限。模块应该创建一个继承AuthorizationProvider的类以便定义它的权限。授权提供者的示例如下:
public class MyAuthorizationProvider : AuthorizationProvider{ public override void SetPermissions(IPermissionDefinitionContext context) { var administration = context.CreatePermission("Administration"); var userManagement = administration.CreateChildPermission("Administration.UserManagement"); userManagement.CreateChildPermission("Administration.UserManagement.CreateUser"); var roleManagement = administration.CreateChildPermission("Administration.RoleManagement"); }}
IPermissionDefinitionContext有获取和创建权限的方法。
权限有一些需要定义的属性:
- Name:系统范围内的唯一名称。最好使用静态字符串定义权限名称而不使用魔法字符串。我们倾向于使用.(dot)符号来定义层级名称,但这不是必须的。你可以设置任何你喜欢的名称,唯一的规则就是它的名字必须唯一。
- DisplayName:一个本地化字符串,用来在UI中显示权限。
- Description:一个本地化字符串,用来在UI中显示权限的定义。
- MultiTenancySides:对于多租户应用,一个权限可以被租户或租主使用。这是一个Flags枚举,从而权限可以在两端使用。
- FeatureDependency:可以用来声明特征的一个依赖。从而,权限只有在特征依赖满足的情况下赋予。它需要一个实现了IFeatureDependency接口的对象。默认的实现类是SimpleFeatureDependency。示例用法:
new SimpleFeatureDependency("MyFeatureName")
一个权限可以有父或子权限。这并不影响权限校验,但有助于在UI层将权限分组。
创建一个授权提供者之后,我们应该在模块的PreInitialize方法中注册它:
Configuration.Authorization.Providers.Add<MyAuthorizationProvider>();
授权提供者自动注册到依赖注入系统。所以,授权提供者可以注入任何依赖来使用一些其他资源创建权限定义。
检查权限
使用AbpAuthorize特性
AbpAuthorize(MVC控制器为AbpMvcAuthorize,Web API控制器为AbpApiAuthorize)是最简单和通用的检查权限的方式。考虑下面的应用服务方法:
[AbpAuthorize("Administration.UserManagement.CreateUser")]public void CreateUser(CreateUserInput input){ //A user can not execute this method if he is not granted for "Administration.UserManagement.CreateUser" permission.}
CreateUser方法不能被没有“Administration.UserManagement.CreateUser”权限的用户调用。
AbpAuthorize特性也检查当前用户是否已登录(使用IAbpSession.UserId)。所以,如果我们为一个方法声明了AbpAuthorize,那ABP只检查是否登录:
[AbpAuthorize]public void SomeMethod(SomeMethodInput input){ //A user can not execute this method if he did not login.}
AbpAuthorize特性注意点
ABP使用动态方法来实现权限拦截。所以,使用AbpAuthorize特性有一些限制:
- 不能用于私有方法。
- 不能用于静态方法。
- 不能用于non-injected类的方法(我们必须使用依赖注入)。
还有,
- 可以用于任何通过接口调用的公共方法(如应用服务使用接口调用)。
- 方法应该为虚方法,如果它被直接从引用类调用(如ASP.NET MVC或Web API控制器)。
- 方法应该为虚方法,如果它是protected。
注意:authorize特性有四种类型:
- 在应用服务中(应用层),我们使用Abp.Authorization.AbpAuthorize特性。
- 在MVC控制器中(网络层),我们使用Abp.Web.Mvc.Authorization.AbpMvcAuthorization特性。
- 在ASP.NET Web API中,我们使用Abp.WebApi.Authorization.AbpApiAuthorize特性。
- 在ASP.NET Core中,我们使用Abp.AspNetCore.Mvc.Authorization.AbpMvcAuthorize特性。
这些不同起源于继承。在应用层,它完全由ABP实现,没有扩展任何类。但是,在MVC和WebAPI,它继承自这些框架的特性。
抑制授权
你可以通过给应用服务添加AbpAllowAnonymous特性来禁用方法或类的授权。MVC、Web API和ASP.NET Core控制器使用AllowAnonymous特性,它是这些框架的本地特性。
使用IPermissionChecker
AbpAuthorize特性足以应对大多数情况,但是肯定有需要在方法体内检查权限的情景。我们可以注入并使用IPermissionChecker接口,实例如下所示:
public void CreateUser(CreateOrUpdateUserInput input){ if (!PermissionChecker.IsGranted("Administration.UserManagement.CreateUser")) { throw new AbpAuthorizationException("You are not authorized to create user!"); } //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.}
当然,你可以编写任何逻辑,因为IsGranted简单的返回true或false(它有异步版本)。如果你简单的检查一个权限并抛出一个异常,你可以使用Authorize方法:
public void CreateUser(CreateOrUpdateUserInput input){ PermissionChecker.Authorize("Administration.UserManagement.CreateUser"); //A user can not reach this point if he is not granted for "Administration.UserManagement.CreateUser" permission.}
因为授权被广泛使用。ApplicationServe和一些其他的基类注入并定义了PermissionChecker属性。因此,在应用服务类,权限检查不用注入就可以使用。
在Razor视图
基础视图类定义了IsGranted方法检查当前用户是否有权限。因此,我们可以有条件的渲染视图。示例:
@if (IsGranted("Administration.UserManagement.CreateUser")){ <button id="CreateNewUserButton" class="btn btn-primary"><i class="fa fa-plus"></i> @L("CreateNewUser")</button>}
客户端(Javascript)
在客户端,我们可以使用在abp.auth命名空间定义的API。在大多数情况下,我们需要检查当前用户是否有一个指定的权限(使用权限名称)。示例:
abp.auth.isGranted(‘Administration.UserManagement.CreateUser‘);
你也可以使用abp.auth.grantedPermissions获取所有授权的权限或abp.auth.allPermissions获取所有在应用中可用的权限。Check abp.auth namespace on runtime for others.
权限管理
我们或许需要权限的定义,这种情况下可以使注入并使用IPermissonManager接口来达到目的。
返回主目录
ABP官方文档翻译 4.4 授权