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

 

注意,這里Kingusn.Liujb.Shared使用netstandard2.0

 

 

將Kingsun.Liujb.Shared添加到Kingsun.Liujb.IDServer.IdentityServer項目引用,替換原來的shared項目。

 MultiTenancyConsts.cs

1
2
3
4
public  class  MultiTenancyConsts
   {
       public  const  bool  IsEnabled =  true ;
   }

 更改數據庫鏈接地址為實際地址:Kingsun.Liujb.IDServer.IdentityServer項目的appsettings.json。

 由於目前沒有使用reids緩存,先行在IDServerIdentityServerModule中將redis相關模塊注釋掉。

 

此處要注釋的地方包括:
1、IdentityServerModule的依賴注入項DependsOn中的typeof(AbpCachingStackExchangeRedisModule)
2、下面這一段

if (!hostingEnvironment.IsDevelopment())
{
  var redis = ConnectionMultiplexer.Connect(configuration["Redis:Configuration"]);
    context.Services
    .AddDataProtection()
    .PersistKeysToStackExchangeRedis(redis, "IdServer-Protection-Keys");
}

 

使用”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的日志管理模塊,可以看出社區版本只提供了領域層及基礎設施層,沒有應用服務層和表示層,也就意味着沒有包含日志管理相關接口及頁面:

 以上依賴要在Kingsun.Liujb.IDServer.Application中使用nuget中添加

然后在IdentityServerModule的依賴注入項DependsOn中加入:

typeof(Volo.Abp.Identity.Web.AbpIdentityWebModule),
typeof(Volo.Abp.TenantManagement.Web.AbpTenantManagementWebModule),
typeof(Kingsun.Liujb.Web.IDServerWebModule)

 

1,新增查詢日志服務

1),先建立服務約束,包括接口,數據傳輸對象。我這里建立了一個名為IAuditServices的接口,約束服務的使用。AuditDto以及GetAuditlogInput這兩個類用於服務數據的傳輸。

 

 聲明如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    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)]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
[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中新建權限,並設置本地化顯示名稱。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
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文件

1
2
3
4
5
6
7
"texts" : {
   "ManageYourProfile" "管理個人資料" ,
   "SamplePageMessage" "IDServer模塊的示例頁面" ,
   "Menu:AuditManagement" "審核日志" ,
   "Audits" "日志" ,
   "Permission:AuditManagement" "審核日志"
}

打開管理頁面,可以看到新增的權限已經可以被管理

 

 3,新增菜單

Kingsun.Liujb.IDServer.Web的Menu目錄

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
( 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);

  此處有一個謬誤,javascript調用createAjax方法時是按照AuditController中的路由[Route("api/IDServer/Audit")]應該是“ajax: abp.libs.datatables.createAjax(kingsun.liujb.iDServer.audit.getAuditsByUsername)”而非“ajax: abp.libs.datatables.createAjax(kingsun.liujb.iDServer.audits.audit.getAuditsByUsername)”,否則程序會報錯。

        此處另一個錯誤,需要在IdServerHttpApiModule上面依賴注入IdServerApplicationModule(請先引用它)

       此處有另一個錯誤,沒有配置AuditLog和AuditDto的AutoMap,需在Kingsun.Liujb.IDServer.Application的IDServerApplicationAutoMapperProfile文件中添加以下配置:

 

            CreateMap<AuditLog, AuditDto>();

 

 本地化:參考權限名稱本地化,修改本地化json文件即可 

 打開頁面

 

 

 這只是一個比較簡單的管理功能,下一篇將使用模塊化的方式添加一個較為復雜的管理模塊:IdentityServer管理模塊。

 

 
分類:  abp
 

此處有另一個錯誤,沒有配置AuditLog和AuditDto的AutoMap,需在Kingsun.Liujb.IDServer.Application的IDServerApplicationAutoMapperProfile文件中添加以下配置:
            CreateMap<AuditLog, AuditDto>();


免責聲明!

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



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