zoukankan      html  css  js  c++  java
  • Abp VNext微服务-从身份认证及授权开始(一)

    Abp-VNext是基于aspnetboilerplate的先行版本,在我看来,具有下面三个特点:

    1,一个全面的技术框架:基本上囊括了.Net 技术栈上各种流行的技术应用,并且在集成度上也做得很好。

    2,基于领域驱动的分层设计模型:提供了DDD分层设计的最佳实践,明确了各层的工作职责

    3,模块化的开发模式

    参考:aspnetboilerplateABP-VNext

    Abp-VNext的特点决定了他在.Net 微服上能大展拳脚,下面从微服务的身份认证及授权开始,看看Abp-Vnext能帮我们做些什么。

    一,基于Abp-Vnext的微服务架构目录

    参考Abp-Vnext的微服务Demo,先把工作目录建立起来

     先建立一个服务,用于用户身份认证及授权管理

    1,建立解决方案:dotnet new sln --name Kingsun.Liujb

    2,建立用于用户身份认证及授权管理的模块:

      切换目录到modules,执行Abp命令:abp new Kingsun.Liujb.IDServer --ui-none -t module -csf。创建一个没有ui的模块。

    3,创建模块后认识一下Abp-vnext的DDD分层架构

     4,按需将模块添加到根解决方案

    二,IdentityServer宿主配置

    切换到microsoftservices目录,

    将Modules目录中的宿主示例中的IdentityServer直接拷过来。切换到shared目录,新建一个类库:Kingusn.Liujb.Shared

    将Kingsun.Liujb.Shared添加到Kingsun.Liujb.IDServer.IdentityServer项目引用,替换原来的shared项目。

     MultiTenancyConsts.cs

      public class MultiTenancyConsts
        {
            public const bool IsEnabled = true;
        }
    

     更改数据库链接地址为实际地址:Kingsun.Liujb.IDServer.IdentityServer项目的appsettings.json。

     由于目前没有使用reids缓存,先行在IDServerIdentityServerModule中将redis相关模块注释掉。

    使用”update-database“命令更新数据到数据库,运行IdentityServer项目后使用默认的用户名:admin。密码:1q2w3E* 登录

    三,添加用户身份管理、租户管理模块

    前面我们见识到了使用ABP-Vnext创建项目的实用性,下面将用使用ABP-VNext的模块化特性快速添加部份管理模块

    先添加身份认证相关的管理模块,安装Nuget包:Volo.Abp.Identity.Web 后在IDServerIdentityServerModule.cs中添加依赖:typeof(Volo.Abp.Identity.Web.AbpIdentityWebModule)。

    运行程序:

     

     同样添加租户管理:Volo.Abp.TenantManagement.Web.AbpTenantManagementWebModule

    四,添加日志查看模块

    查看Abp-vnex的日志管理模块,可以看出社区版本只提供了领域层及基础设施层,没有应用服务层和表示层,也就意味着没有包含日志管理相关接口及页面:

    1,新增查询日志服务

    1),先建立服务约束,包括接口,数据传输对象。我这里建立了一个名为IAuditServices的接口,约束服务的使用。AuditDto以及GetAuditlogInput这两个类用于服务数据的传输。

     声明如下:

       public interface IAuditServices : IApplicationService
        {
            System.Threading.Tasks.Task<PagedResultDto<AuditDto>> GetAuditsByUsernameAsync(GetAuditlogInput input);
            System.Threading.Tasks.Task<PagedResultDto<AuditDto>> GetListAsync();
        }
    
    public class AuditDto: EntityDto<Guid>
        {
            public string ApplicationName { get; set; }
            public string UserId { get; set; }
            public string UserName { get; set; }
            public string TenantName { get; set; }
            public DateTime ExecutionTime { get; set; }
            public int ExecutionDuration { get; set; }
            public string ClientIpAddress { get; set; }
            public string ClientName { get; set; }
            public string BrowserInfo { get; set; }
            public string HttpMethod { get; set; }
            public string Url { get; set; }
            public string Exceptions { get; set; }
            public int HttpStatusCode { get; set; }
        }
    
     public class GetAuditlogInput: PagedAndSortedResultRequestDto
        {
            public string Filter { get; set; }
        }
    

    2),实现服务

    在Kingsun.Liujb.IDServer.Application包中实现具体的服务


        [Authorize(IDServerPermissions.Audits.AuditMannage)]
    public class AuditServices : IDServerAppService, IAuditServices
        {
            private readonly IAuditLogRepository _auditLogRepository;
            public AuditServices(IAuditLogRepository auditLogRepository)
            {
                this._auditLogRepository = auditLogRepository;
            }
            public async System.Threading.Tasks.Task<PagedResultDto<AuditDto>> GetAuditsByUsernameAsync(GetAuditlogInput input)
            {
                long count = await _auditLogRepository.GetCountAsync(userName: input.Filter);
                var list = await _auditLogRepository.GetListAsync(
                    skipCount: input.SkipCount,
                    maxResultCount: input.MaxResultCount,
                    userName: input.Filter,
                    sorting: input.Sorting
                    );
                return new PagedResultDto<AuditDto>()
                {
                    TotalCount = count,
                    Items = ObjectMapper.Map<List<AuditLog>, List<AuditDto>>(list)
                };
            }
    
            public async Task<PagedResultDto<AuditDto>> GetListAsync()
            {
                long count = await _auditLogRepository.GetCountAsync();
                var list = await _auditLogRepository.GetListAsync();
                return new PagedResultDto<AuditDto>()
                {
                    TotalCount = count,
                    Items = ObjectMapper.Map<List<AuditLog>, List<AuditDto>>(list)
                };
            }
        }
    

     暴露API

    Kingsun.Liujb.IDServer.HttpApi

     [RemoteService]
        [Route("api/IDServer/Audit")]
        [Authorize(IDServerPermissions.Audits.AuditMannage)]
        public class AuditController : IDServerController, IAuditServices
        {
            private readonly IAuditServices _iDServerAuditService;
            public AuditController(IAuditServices _iDServerAuditService)
            {
                this._iDServerAuditService = _iDServerAuditService;
            }
            [HttpGet]
            [Route("GetAuditsByUsername")]
            public async Task<PagedResultDto<AuditDto>> GetAuditsByUsernameAsync(GetAuditlogInput input)
            {
                return await _iDServerAuditService.GetAuditsByUsernameAsync(input);
            }
    
            [HttpGet]
            [Route("GetList")]
            public async Task<PagedResultDto<AuditDto>> GetListAsync()
            {
                return await _iDServerAuditService.GetListAsync();
            }
        }

    2,新增访问权限  

     对服务访问进行授权管理。

    在Kingsun.Liujb.IDServer.Application.Contracts包的PermissionDefinitionProvider中新建权限,并设置本地化显示名称。

        public class IDServerPermissionDefinitionProvider : PermissionDefinitionProvider
        {
            public override void Define(IPermissionDefinitionContext context)
            {
                var auditGroup = context.AddGroup(IDServerPermissions.GroupName, L("Permission:AuditManagement"));
                auditGroup.AddPermission(IDServerPermissions.Audits.AuditMannage, L("Permission:AuditManagement"), Volo.Abp.MultiTenancy.MultiTenancySides.Host);
            }
    
            private static LocalizableString L(string name)
            {
                return LocalizableString.Create<IDServerResource>(name);
            }
        }
    
        public class IDServerPermissions
        {
            public const string GroupName = "IDServer";
            public static class Audits
            {
                public const string AuditMannage = GroupName + ".Audits";
            }
            public static string[] GetAll()
            {
                return ReflectionHelper.GetPublicConstantsRecursively(typeof(IDServerPermissions));
            }
        }
    

     权限名称本地化:Kingsun.Liujb.IDServer.Domain.Shared中的Localization目录中修改本地化Json文件

      "texts": {
        "ManageYourProfile": "管理个人资料",
        "SamplePageMessage": "IDServer模块的示例页面",
        "Menu:AuditManagement": "审核日志",
        "Audits": "日志",
        "Permission:AuditManagement": "审核日志"
      }
    

    打开管理页面,可以看到新增的权限已经可以被管理

     3,新增菜单

    Kingsun.Liujb.IDServer.Web的Menu目录

     public class IDServerMenuContributor : IMenuContributor
        {
            public async Task ConfigureMenuAsync(MenuConfigurationContext context)
            {
                if (context.Menu.Name == StandardMenus.Main)
                {
                    await ConfigureMainMenu(context);
                }
            }
            private async Task ConfigureMainMenu(MenuConfigurationContext context)
            {
                //Add main menu items.
                var administrationMenu = context.Menu.GetAdministration(); 
                var l = context.GetLocalizer<IDServerResource>();
                var AuditlogsMenuItem = new ApplicationMenuItem(IDServerMenus.AuditManagementGroup, l["Menu:AuditManagement"], icon: "fa fa-file-text-o");
                administrationMenu.AddItem(AuditlogsMenuItem);
                if (await context.IsGrantedAsync(IDServerPermissions.Audits.AuditMannage))
                {
                    AuditlogsMenuItem.AddItem(new ApplicationMenuItem(IDServerMenus.AuditManagementSelect, 
                        l["Audits"], url: "~/Audit"));
                }
            }
        }
    
       private const string Prefix = "IDServer";
            public const string AuditManagementGroup = "AuditManagement";
            public const string AuditManagementSelect = AuditManagementGroup + ".AuditLogs";
    

    菜单名称本地化参考权限名称本地化,修改本地化json文件即可。

    打开管理页面,看到管理菜单已经添加了日志目录

    4,新增日志查看页面

     

     Index.cshtml

    @page
    @using Microsoft.Extensions.Localization
    @using Kingsun.Liujb.IDServer.Localization
    @model Kingsun.Liujb.IDServer.Web.Pages.IDServer.IndexModel
    @inject IStringLocalizer<IDServerResource> L
    @section scripts{
        <abp-script src="/Pages/Audit/Index.js" />
    }
    <abp-card>
        <abp-card-header>
            <abp-row>
                <abp-column size-md="_6">
                    <abp-card-title>@L["Audits"]</abp-card-title>
                </abp-column>
            </abp-row>
        </abp-card-header>
        <abp-card-body>
            <abp-table striped-rows="true" id="AuditsTable"></abp-table>
        </abp-card-body>
    </abp-card>
    

    Index.js

    (function ($) {
        var l = abp.localization.getResource('IDServer');
        var dataTable = $('#AuditsTable').DataTable(
            abp.libs.datatables.normalizeConfiguration({
                serverSide: true,
                paging: true,
                searching: true,
                scrollX: true,
                order: [[1, "asc"]],
                ajax: abp.libs.datatables.createAjax(kingsun.liujb.iDServer.audits.audit.getAuditsByUsername),
                columnDefs: [
                    {
                        title:l("UserName"),
                        data:"userName"
                    },
                    {
                        title: l( "ExecutionTime"),
                        data: "executionTime"
                    },
                    {
                        title: l("Url"),
                        data: "url"
                    },
                    {
                        title: l("HttpMethod"),
                        data: "httpMethod"
                    },
                    {
                        title: l("HttpStatusCode"),
                        data: "httpStatusCode"
                    }
                ]
            })
        )
    })(jQuery);
    

      

     本地化:参考权限名称本地化,修改本地化json文件即可 

     打开页面

     这只是一个比较简单的管理功能,下一篇将使用模块化的方式添加一个较为复杂的管理模块:IdentityServer管理模块。

  • 相关阅读:
    基于VIP的keepalived高可用架构
    高性能Nginx最佳实践
    Ubuntu安装Nginx
    Synchronized总结及底层原理分析#网易微专业# #Java#
    springboot Restful开发
    Volatile详解
    IOC知识点详细汇总
    python 一个函数让你决定你的二维码
    用python批量生成简单的xml文档
    基于tensorflow搭建一个神经网络
  • 原文地址:https://www.cnblogs.com/liujiabing/p/14077818.html
Copyright © 2011-2022 走看看