• 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无删除操作,附截图如下:

     

     以上就是本项目模板权限配置的内容,在此记录为了加深印象同时方便后者参考学习!



  • 相关阅读:
    JavaScript--数组的声明与创建
    JavaScript--Object对象的两种表示方法
    上下文模式
    Ajax详解
    JS面向对象之原型链
    JS面向对象特性和值类型与复合类型
    JS面向对象使用面向对象进行开发
    JS中的递归
    前端协作流程
    JavaScript中内存使用规则--堆和栈
  • 原文地址:https://www.cnblogs.com/become/p/15958743.html
Copyright © 2020-2023  润新知