前面幾篇已經說到模塊的增刪改查功能的實現,接下來咋們看看怎么實現系統的權限配置和實現
一、自定義權限名稱
在項目TestApp.BookStore.Application.Contracts的Permissions文件下的BookStorePermissions類中,腳本如下:
namespace TestApp.BookStore.Permissions;
public static class BookStorePermissions
{
public const string GroupName = "BookStore";
//Add your own permission names. Example:
//public const string MyPermission1 = GroupName + ".MyPermission1";
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";
}
}
二、權限定義
在項目TestApp.BookStore.Application.Contracts的Permissions文件下的BookStorePermissionDefinitionProvider類中,腳本如下:
using TestApp.BookStore.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace TestApp.BookStore.Permissions;
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var myGroup = context.AddGroup(BookStorePermissions.GroupName,L("Permission:BookStore"));
//Define your own permissions here. Example:
//myGroup.AddPermission(BookStorePermissions.MyPermission1, L("Permission:MyPermission1"));
var booksPermission = myGroup.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);
}
}
- 定義BookStorePermissions.Books.Default、Create、Edit、Delete時千萬注意別寫重復了,系統一運行就會報Permissions.Books重復定義錯誤
- 這個類定義了一個 權限組 (在UI上分組權限, 下文會看到) 和 權限組中的4個權限. 而且, 創建, 編輯 和 刪除 是
BookStorePermissions.Books.Default
權限的子權限. 僅當父權限被選擇時, 子權限才能被選擇
里面有用到本地化文本,所以又得配置一下本地化文本(TestApp.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"
此時就可以在權限頁面(管理>身份認證管理>角色>操作>權限)看到所配置的權限目錄,如下:

此時就可以在系統配置自己的所需的權限,但是會發現一個問題,配置好了不會生效,那是因為我們只是實現的權限配置,還沒有完整在增刪改查的操作點使用對應的權限配置,具體操作如下
三、應用層和HTTP API設置權限策略
TestApp.BookStore.Application項目Books文件夾,打開 the BookAppService
類, 設置策略名稱為上面定義的權限名稱。腳本如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using TestApp.BookStore.Permissions;
namespace TestApp.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
{
public BookAppService(IRepository<Book, Guid> repositoty)
: base(repositoty)
{
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 自動使用這些服務
四、Razor頁面授權
TestApp.BookStore.Web項目打開 BookStoreWebModule
在 ConfigureServices
方法中加入以下代碼:
Configure<RazorPagesOptions>(options =>
{
options.Conventions.AuthorizePage("/Books/Index", BookStorePermissions.Books.Default);
options.Conventions.AuthorizePage("/Books/CreateModal", BookStorePermissions.Books.Create);
options.Conventions.AuthorizePage("/Books/EditModal", BookStorePermissions.Books.Edit);
});
五、菜單(List)/新建(Create)/編輯(Edit)/刪除(Delete)操作點使用權限配置
- 菜單(List)
- TestApp.BookStore.Web項目Menus文件夾BookStoreMenuContributor類,將原來的BookStore菜單腳本:
context.Menu.AddItem(
new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
).AddItem(
new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
)
)
);
修改為(就是加上權限配置判斷):
var bookStoreMenu = new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
);
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
{
bookStoreMenu.AddItem(new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
));
}
- 新建(Create)
- 打開
Pages/Books/Index.cshtml
文件將之前的New book按鈕腳本,修改為:
@if (await AuthorizationService.IsGrantedAsync(BookStorePermissions.Books.Create))
{
<abp-button id="NewBookButton"
text="@L["NewBook"].Value"
icon="plus"
button-type="Primary"/>
}
最終Index.cshtml腳本如下:
@page
@using TestApp.BookStore.Localization
@using TestApp.BookStore.Web.Pages.Books
@using TestApp.BookStore.Permissions
@using Microsoft.Extensions.Localization
@using Microsoft.AspNetCore.Authorization
@model TestApp.BookStore.Web.Pages.Books.IndexModel
@inject IStringLocalizer<BookStoreResource> L
@inject IAuthorizationService AuthorizationService
@section scripts
{
<abp-script src="/Pages/Books/Index.js"/>
}
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["Books"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-right">
@if (await AuthorizationService.IsGrantedAsync(BookStorePermissions.Books.Create))
{
<abp-button id="NewBookButton"
text="@L["NewBook"].Value"
icon="plus"
button-type="Primary"/>
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="BooksTable"></abp-table>
</abp-card-body>
</abp-card>
-
- 加入
@inject IAuthorizationService AuthorizationService
以訪問授權服務.
- 使用
@if (await AuthorizationService.IsGrantedAsync(BookStorePermissions.Books.Create))
檢查圖書創建權限, 條件顯示 新建圖書 按鈕.
-
- 編輯(Edit)
- 打開
Pages/Books/Index.js
文件將之前的Edit按鈕腳本,修改為:
{
text: l('Edit'),
visible: abp.auth.isGranted('BookStore.Books.Edit'), //CHECK for the PERMISSION
action: function (data) {
editModal.open({ id: data.record.id });
}
},
- 刪除(Delete)
- 打開
Pages/Books/Index.js
文件將之前的Delete按鈕腳本,修改為:
{
text: l('Delete'),
visible: abp.auth.isGranted('BookStore.Books.Delete'), //CHECK for the PERMISSION
confirmMessage: function (data) {
return l(
'BookDeletionConfirmationMessage',
data.record.name
);
},
action: function (data) {
testApp.bookStore.books.book
.delete(data.record.id)
.then(function () {
abp.notify.info(
l('SuccessfullyDeleted')
);
dataTable.ajax.reload();
});
}
}
最終js腳本如下:
$(function () {
var l = abp.localization.getResource('BookStore');
//獲取列表
var dataTable = $('#BooksTable').DataTable(
abp.libs.datatables.normalizeConfiguration({
serverSide: true,
paging: true,
order: [[1, "asc"]],
searching: false,
scrollX: true,
ajax: abp.libs.datatables.createAjax(testApp.bookStore.books.book.getList),
columnDefs: [
{
title: l('Actions'),
rowAction: {
items:
[
{
text: l('Edit'),
visible: abp.auth.isGranted('BookStore.Books.Edit'), //CHECK for the PERMISSION
action: function (data) {
editModal.open({ id: data.record.id });
}
},
{
text: l('Delete'),
visible: abp.auth.isGranted('BookStore.Books.Delete'), //CHECK for the PERMISSION
confirmMessage: function (data) {
return l(
'BookDeletionConfirmationMessage',
data.record.name
);
},
action: function (data) {
testApp.bookStore.books.book
.delete(data.record.id)
.then(function () {
abp.notify.info(
l('SuccessfullyDeleted')
);
dataTable.ajax.reload();
});
}
}
]
}
},
{
title: l('Name'),
data: "name"
},
{
title: l('Type'),
data: "type",
render: function (data) {
return l('Enum:BookType:' + data);
}
},
{
title: l('PublishDate'),
data: "publishDate",
render: function (data) {
return luxon
.DateTime
.fromISO(data, {
locale: abp.localization.currentCulture.name
}).toLocaleString();
}
},
{
title: l('Price'),
data: "price"
},
{
title: l('CreationTime'), data: "creationTime",
render: function (data) {
return luxon
.DateTime
.fromISO(data, {
locale: abp.localization.currentCulture.name
}).toLocaleString(luxon.DateTime.DATETIME_SHORT);
}
}
]
})
);
//新增操作
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
createModal.onResult(function () {
dataTable.ajax.reload();
});
$('#NewBookButton').click(function (e) {
e.preventDefault();
createModal.open();
});
//修改操作(columnDefs新增Actions操作列)
var editModal = new abp.ModalManager(abp.appPath + 'Books/EditModal');
editModal.onResult(function () {
dataTable.ajax.reload();
});
})
在此配置權限,測試勾選Creating new books,則Book列表就有New book按鈕,其他操作也是如此。本文測試截圖admin無刪除操作,附截圖如下:


以上就是本項目模板權限配置的內容,在此記錄為了加深印象同時方便后者參考學習!