ABP框架入門學習(五)——權限配置


前面幾篇已經說到模塊的增刪改查功能的實現,接下來咋們看看怎么實現系統的權限配置和實現

一、自定義權限名稱

在項目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無刪除操作,附截圖如下:

 

 

 

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



 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM