Web应用程序开发教程 - 第五章: 授权
关于本教程
在本系列教程中, 你将构建一个名为 Acme.BookStore
的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
- Entity Framework Core 做为ORM提供程序.
- Blazor Server 做为UI框架.
本教程分为以下部分:
- Part 1: 创建服务端
- Part 2: 图书列表页面
- Part 3: 创建,更新和删除图书
- Part 4: 集成测试
- Part 5: 授权 (本章)
- Part 6: 作者: 领域层
- Part 7: 作者: 数据库集成
- Part 8: 作者: 应用服务层
- Part 9: 作者: 用户页面
- Part 10: 图书到作者的关系
下载源码
本教程根据你的UI 和 数据库偏好有多个版本,我们准备了几种可供下载的源码组合:
如果你在Windows中遇到 "文件名太长" 或 "解压错误", 很可能与Windows最大文件路径限制有关. Windows文件路径的最大长度为250字符. 为了解决这个问题,参阅 在Windows 10中启用长路径.
如果你遇到与Git相关的长路径错误, 尝试使用下面的命令在Windows中启用长路径. 参阅 https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path
git config --system core.longpaths true
权限
ABP框架提供了一个基于ASP.NET Core授权基础架构的授权系统. 基于标准授权基础架构的一个主要功能是添加了 权限系统, 这个系统允许定义权限并且根据角色, 用户或客户端启用/禁用权限.
权限名称
权限必须有唯一的名称 (一个 字符串
). 最好的方法是把它定义为一个 常量
, 这样我们就可以重用这个权限名称了.
打开 Acme.BookStore.Application.Contracts
项目中的 BookStorePermissions
类 (位于 Permissions
文件夹) 并替换为以下代码:
namespace Acme.BookStore.Permissions
{
public static class BookStorePermissions
{
public const string GroupName = "BookStore";
public static class Books
{
public const string Default = GroupName + ".Books";
public const string Create = Default + ".Create";
public const string Edit = Default + ".Edit";
public const string Delete = Default + ".Delete";
}
}
}
权限名称具有层次结构. 例如, "创建图书" 权限被定义为 BookStore.Books.Create
. ABP不强制必须如此, 但这是一种有益的做法.
权限定义
在使用权限前必须定义它们.
打开 Acme.BookStore.Application.Contracts
项目中的 BookStorePermissionDefinitionProvider
类 (位于 Permissions
文件夹) 并替换为以下代码:
using Acme.BookStore.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace Acme.BookStore.Permissions
{
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var bookStoreGroup = context.AddGroup(BookStorePermissions.GroupName, L("Permission:BookStore"));
var booksPermission = bookStoreGroup.AddPermission(BookStorePermissions.Books.Default, L("Permission:Books"));
booksPermission.AddChild(BookStorePermissions.Books.Create, L("Permission:Books.Create"));
booksPermission.AddChild(BookStorePermissions.Books.Edit, L("Permission:Books.Edit"));
booksPermission.AddChild(BookStorePermissions.Books.Delete, L("Permission:Books.Delete"));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<BookStoreResource>(name);
}
}
}
这个类定义了一个 权限组 (在UI上分组权限, 下文会看到) 和 权限组中的4个权限. 而且, 创建, 编辑 和 删除 是 BookStorePermissions.Books.Default
权限的子权限. 仅当父权限被选择时, 子权限才能被选择.
最后, 编辑本地化文件 (Acme.BookStore.Domain.Shared
项目的 Localization/BookStore
文件夹中的 en.json
) 定义上面使用的本地化键:
"Permission:BookStore": "Book Store",
"Permission:Books": "Book Management",
"Permission:Books.Create": "Creating new books",
"Permission:Books.Edit": "Editing the books",
"Permission:Books.Delete": "Deleting the books"
本地化键名可以是任意的, 并没有强制的规则. 但我们推荐上面使用的约定. 简体中文翻译请打开
zh-Hans.json
文件 ,并将"Texts"对象中对应的值替换为中文.
权限管理界面
完成权限定义后, 可以在权限管理模态窗口看到它们.
在管理 -> Identity -> 角色 页面, 选择admin角色的 权限 操作, 打开权限管理模态窗口:
授予你希望的权限并保存.
提示: 如果运行
Acme.BookStore.DbMigrator
应用程序, 新权限会被自动授予admin.
授权
现在, 你可以使用权限授权图书管理.
应用层 和 HTTP API
打开 the BookAppService
类, 设置策略名称为上面定义的权限名称.
using System;
using Acme.BookStore.Permissions;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Books
{
public class BookAppService :
CrudAppService<
Book, //The Book entity
BookDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdateBookDto>, //Used to create/update a book
IBookAppService //implement the IBookAppService
{
public BookAppService(IRepository<Book, Guid> repository)
: base(repository)
{
GetPolicyName = BookStorePermissions.Books.Default;
GetListPolicyName = BookStorePermissions.Books.Default;
CreatePolicyName = BookStorePermissions.Books.Create;
UpdatePolicyName = BookStorePermissions.Books.Edit;
DeletePolicyName = BookStorePermissions.Books.Delete;
}
}
}
加入代码到构造器. 基类中的 CrudAppService
自动在CRUD操作中使用这些权限. 这不仅实现了 应用服务 的安全性, 也实现了 HTTP API 安全性, 因为如前解释的, HTTP API 自动使用这些服务. (参阅 自动 API controllers).
在稍后开发作者管理功能时, 你将会看到声明式授权, 使用
[Authorize(...)]
特性.
下一章
查看本教程的下一章.