您的位置:首页 > 其它

ABP官方文档(二十六)【权限认证】

2017-11-03 10:21 453 查看

4.4 ABP应用层 - 权限认证

几乎所有的企业级应用程序都会有不同级别的权限验证。权限验证是用于检查用户是否允许某些指定操作。Abp有基础设施让你来实现权限验证。

注意:关于IPermissionChecker接口

Abp权限系统使用IPermissionChecker去检查授权。同时你可以根据需要实现你自己的方式,在module-zero项目中已经完整实现了。如果IPermissionChecker没有被实现,NullPermissionChecker会被使用于授权所有权限给每个人。

4.4.1 定义权限

在使用验证权限前,我们需要为每一个操作定义唯一的权限。Abp的设计是基于模块化,所以不同的模块可以有不同的权限。为了定义权限,一个模块应该创建AuthorizationProvider的派生类。MyAuthorizationProvider继承自AuthorizationProvider,换句话说就是AuthorizationProvider派生出MyAuthorizationProvider。例子如下:

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:系统范围内的唯一名字。把它定义为一个字符串常量是个不错的注意。我们倾向于将 .(点) 分割不同的层级,但并不要求这么做。你可以设置你任何喜欢的名字。唯一的规则就是这个名字必须是唯一的。

Display Name:使用一个本地化的字符串去显示权限到UI。

Description:和Display Name类似。

MultiTenancySides:对租户应用程序,一个权限可以基于租户或者Host。这是个枚举标识,因此该权限双方都可以使用(租户或者Host)。

featureDependency:能够被用来描述某个被依赖的功能。那么,只有在该依赖的功能被满足的情况下该权限才被授予。该参数是一个实现了 IFeatureDependency 的对象。SimpleFeatureDependency 默认实现了该接口。使用示例:new SimpleFeatureDependency(“MyFeatureName”)

一个权限可以有父权限和子权限。当然,这不会影响权限检查,它只是在UI层对权限归类有好处。创建Authorization providers之后,我们应该在模块的PreIntialize方法对它进行注册。如下:

Configuration.Authorization.Providers.Add<MyAuthorizationProvider>()


Authorization providers 会自动注册到依赖注入系统中。因此,authorization provider可以注入任何依赖(像是Repository)从而使用其他资源去创建权限定义。

4.4.2 检查权限

(1)使用AbpAuthorize特性(Using AbpAuthorize attribute)

AbpAuthorize (AbpMvcAuthorize 对应MVC控制器,AbpApiAuthorize 对应 Web API控制器)特性是最简单和常用的方法去检查权限。请考虑如下application service方法:

[AbpAuthorize("Administration.UserManagement.CreateUser")]
public void CreateUser(CreateUserInput input)
{
//如果用户没有被授予 "Administration.UserManagement.CreateUser" 权限,那么他不能执行这个方法.
}


没有获得 Administration.UserManagement.CreateUser 权限的用户不能够调用CreateUser。

AbpAuthorize 特性也检查当前用户是否登录 (使用 IAbpSession.UserId)。因此,如果我们将某个方法声明为AbpAuthorize 特性,它至少会检查用户是否登录。代码如下:

[AbpAuthorize]
public void SomeMethod(SomeMethodInput input)
{
//如果用户没有登录,那么他不能执行该方法。
}


(2)AbpAuthorize属性说明(AbpAuthorize attribute notes)

Abp使用动态方法拦截进行权限验证。因此,使用AbpAuthorize特性的方法会有些限制。如下:

不能应用于私有(private)方法

不能应用于静态(static)方法

不能应用于非注入(non-injected)类(我们必须使用依赖注入)。

此外,

AbpAuthorize特性可以应用于任何的Public方法,如果此方法被接口调用(比如在Application Services中通过接口调用)

方法是虚(virtual)方法,如果此方法直接被类引用进行调用(像是ASP.NET MVC 或 Web API 的控制器)。

方式是虚(virtual)方法,如果此方法是protected。

注意:有四种 AbpAuthorize 特性:

在应用程序服务中(application layer),我们使用 Abp.Authorization.AbpAuthorize

在MVC控制器(web layer)中,我们使用 Abp.Web.Mvc.Authorization.AbpMvcAuthorize

在ASP.NET Web API,我们使用 Abp.WebApi.Authorization.AbpApiAuthorize

在ASP.NET Core,我们使用 Abp.AspNetCore.Mvc.Authorization.AbpMvcAuthorize

这种不同来自于继承。在Application 层,它完全是由Abp自己实现没有扩展自任何类。但是,在MVC和Web API中它继承自它们框架中各自的 Authorize 特性。

Suppress Authorization

你可以对应用服务中某个方法或者类使用 AbpAllowAnonymous 特性来禁用认证许可。对于在MVC,Web API以及ASP.NET Core控制器禁用认证许可,你应该使用它们各自框架中的 AllowAnonymous 特性。

(3)使用IPermissionChecker

AbpAuthorize 适用于大部分的情况,但是某些情况下,我们还是需要自己在方法体里进行权限验证。我们可以注入和使用 IPermissionChecker 对象。如下边的代码所示:

public void CreateUser(CreateOrUpdateUserInput input)
{
if (!PermissionChecker.IsGranted("Administration.UserManagement.CreateUser"))
{
throw new AbpAuthorizationException("You are not authorized to create user!");
}

//如果该用户没有 "Administration.UserManagement.CreateUser" 的权限,那么它就不能运行到这个地方。
}


当然,你可以写入任何逻辑,由于 IsGranted 方法只是简单返回true或false(它还有异步版本哦)。如你简单的检查一个权限并抛出一个异常如上边代码那样,你可以用 Authorize 方法:

public void CreateUser(CreateOrUpdateUserInput input)
{
PermissionChecker.Authorize("Administration.UserManagement.CreateUser");

//如果该用户没有 "Administration.UserManagement.CreateUser" 的权限,那么它就不能运行到这个地方。
}


由于权限验证通常实现于Application层,ApplicationService 和一些通用基类注入和定义了PermissionChecker属性。因此,权限检查器允许你在Application Service类使用,而不需要显式注入。

在Razor视图中

在视图基类中定义了 IsGranted 方法来检查当前用户时候具有某个权限。因此我们可以有条件的来渲染视图,例如:

@if (IsGranted("Administration.UserManagement.CreateUser"))
{
<button id="CreateNewUserButton" class="btn btn-primary"><i class="fa fa-plus"></i> @L("CreateNewUser")</button>
}


客户端

在客户端,我们可以使用定义在 abp.auth 命名空间中的API。在大多数情况下,我们需要检查当前用户时候具有指定的权限。例如:

abp.auth.isGranted('Administration.UserManagement.CreateUser');


你也可以使用 abp.auth.grantedPermissions 来获取所有的权限或者使用 abp.auth.allPermissions 来获取应用中所有有效的权限名称。

Permission Manager

我们可能需要定义一些权限。 在这种情况下,我们可以注入 IPermissionManager 来使用它们。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: