日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ABP vNext微服务架构详细教程——分布式权限框架(下)

發(fā)布時(shí)間:2023/12/4 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ABP vNext微服务架构详细教程——分布式权限框架(下) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

3

公共組件

添加公共類庫Demo.Permissions,編輯Demo.Permissions.csproj文件,將?<Project Sdk="Microsoft.NET.Sdk">?改為:

<Project Sdk="Microsoft.NET.Sdk.Web">

為Demo.Permissions項(xiàng)目添加Nuget引用Volo.Abp.Core和Microsoft.AspNetCore.Http,并應(yīng)用Demo.Identity.HttpApi.Client項(xiàng)目。

在Demo.Permissions中添加權(quán)限關(guān)系枚舉PermissionRelation如下:

namespace Demo.Permissions;/// <summary> /// 權(quán)限關(guān)系枚舉 /// </summary> public enum PermissionRelation {/// <summary>/// 需要同時(shí)滿足/// </summary>And,/// <summary>/// 只需要滿足任意一項(xiàng)/// </summary>Or,}

在Demo.Permissions中添加CusPermissionAttribute特性,用于標(biāo)記接口所需要的權(quán)限,如下:

namespace Demo.Permissions;/// <summary> /// 自定義權(quán)限特性 /// </summary> [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)] public class CusPermissionAttribute : Attribute {/// <summary>/// 權(quán)限編碼/// </summary>public string[] PermissionCode { get; }/// <summary>/// 權(quán)限之間的關(guān)系/// </summary>public PermissionRelation Relation { get; } = PermissionRelation.And;/// <summary>/// 構(gòu)造函數(shù)/// </summary>/// <param name="relation">權(quán)限關(guān)系</param>/// <param name="permissionCodes">權(quán)限編碼</param>public CusPermissionAttribute(PermissionRelation relation,params string[] permissionCodes){Relation = relation;PermissionCode = permissionCodes;}/// <summary>/// 構(gòu)造函數(shù)/// </summary>/// <param name="permissionCodes">權(quán)限編碼</param>public CusPermissionAttribute(params string[] permissionCodes){PermissionCode = permissionCodes;} }

其中一個(gè)特性可以聲明多個(gè)權(quán)限碼,Relation表示該特性中所有權(quán)限碼間的關(guān)系,如果為And,需要用戶具有該特性聲明的所有權(quán)限碼才可通過驗(yàn)證,若為Or,則表示用戶只要具有任意一個(gè)或多個(gè)該特性中聲明的權(quán)限就可通過驗(yàn)證。

一個(gè)接口可以聲明多個(gè)特性,特性與特性之間是And關(guān)系。

在Demo.Permissions中添加權(quán)限驗(yàn)證中間件CusPermissionMiddleware如下:

using Demo.Identity.Permissions; using Microsoft.AspNetCore.Http.Features; using Volo.Abp.Users;namespace Demo.Permissions;/// <summary> /// 自定義權(quán)限中間件 /// </summary> public class CusPermissionMiddleware {private readonly RequestDelegate _next;private readonly ICurrentUser _currentUser;private readonly ISysPermissionAppService _service;public CusPermissionMiddleware(RequestDelegate next, ICurrentUser currentUser, ISysPermissionAppService service){_next = next;_currentUser = currentUser;_service = service;}public async Task InvokeAsync(HttpContext context){var attributes = context.GetEndpoint()?.Metadata.GetOrderedMetadata<CusPermissionAttribute>();//如果不存在CusPermissionAttribute特性則該接口不需要權(quán)限驗(yàn)證,直接跳過if (attributes==null||attributes.Count==0){await _next(context);return;}//如果需要權(quán)限驗(yàn)證則必須是已登錄用戶,否則返回401if (_currentUser.Id == null){context.Response.StatusCode = 401;return;}//獲取用戶權(quán)限var userPermisions = (await _service.GetUserPermissionCode((Guid) _currentUser.Id)).ToHashSet();//比對(duì)權(quán)限 如果無權(quán)限則返回403foreach (var cusPermissionAttribute in attributes){var flag = cusPermissionAttribute.Relation == PermissionRelation.And? cusPermissionAttribute.PermissionCode.All(code => userPermisions.Contains(code)): cusPermissionAttribute.PermissionCode.Any(code => userPermisions.Contains(code));if (!flag){context.Response.StatusCode = 403;return;}}await _next(context);} }

在接口調(diào)用時(shí),該中間件會(huì)獲取接口所聲明的權(quán)限特性,并調(diào)用身份管理服務(wù)接口獲取當(dāng)前用戶所持有的權(quán)限碼,按特性順序依次驗(yàn)證。

在Demo.Permissions中添加PermissionRegistor類,用于在聚合服務(wù)啟動(dòng)時(shí)讀取代碼中聲明的所有權(quán)限碼,并注冊(cè)到身份管理服務(wù)。代碼如下:

using System.ComponentModel; using Demo.Identity.Permissions.Dto;namespace Demo.Permissions;/// <summary> /// 權(quán)限注冊(cè) /// </summary> public static class PermissionRegistor {/// <summary>/// 在指定類型中獲取權(quán)限集合/// </summary>/// <param name="serviceName">服務(wù)名稱</param>/// <typeparam name="T">類型</typeparam>/// <returns></returns>internal static List<SysPermissionDto> GetPermissions<T>(string serviceName){List<SysPermissionDto> result = new List<SysPermissionDto>();Type type = typeof(T);var fields = type.GetFields().Where(x=>x.IsPublic&&x.IsStatic);foreach (var field in fields){string code = field.GetValue(null).ToString();string name = "";object[] objs = field.GetCustomAttributes(typeof(DescriptionAttribute), false); //獲取描述屬性if (objs != null && objs.Length > 0){DescriptionAttribute descriptionAttribute = (DescriptionAttribute) objs[0];name = descriptionAttribute.Description;}string parentCode = null;if (code.Contains(".")){parentCode = code.Substring(0, code.LastIndexOf('.'));}result.Add(new SysPermissionDto(){Name = name,Code = code,ParentCode = parentCode,ServiceName = serviceName,});}return result;} }

在Demo.Permissions中添加CusPermissionExtensions類,提供IApplicationBuilder的擴(kuò)展方法,用于注冊(cè)中間件和注冊(cè)權(quán)限,代碼如下:

using Demo.Identity.Permissions;namespace Demo.Permissions;public static class CusPermissionExtensions {/// <summary>/// 注冊(cè)自定義權(quán)限/// </summary>public static void UseCusPermissions<T>(this IApplicationBuilder app, string serviceName){app.RegistPermissions<T>(serviceName);app.UseMiddleware<CusPermissionMiddleware>();}/// <summary>/// 注冊(cè)權(quán)限/// </summary>/// <param name="app"></param>/// <param name="serviceName">服務(wù)名稱</param>/// <typeparam name="T"></typeparam>private static async Task RegistPermissions<T>(this IApplicationBuilder app, string serviceName){var service = app.ApplicationServices.GetService<ISysPermissionAppService>();var permissions = PermissionRegistor.GetPermissions<T>(serviceName);await service.RegistPermission(serviceName, permissions);} }

在Demo.Permissions中添加DemoPermissionsModule類如下:

using Demo.Identity; using Volo.Abp.Modularity;namespace Demo.Permissions;[DependsOn(typeof(IdentityHttpApiClientModule))] public class DemoPermissionsModule:AbpModule {}

4

聚合服務(wù)層

在聚合服務(wù)層,我們就可以使用剛才創(chuàng)建的Demo.Permissions類庫,這里以商城服務(wù)為例。

在Demo.Store.Application項(xiàng)目中添加Demo.Permissions的項(xiàng)目引用,并為DemoStoreApplicationModule類添加以下特性:

[DependsOn(typeof(DemoPermissionsModule))]

在Demo.Store.Application項(xiàng)目中添加在PermissionLab類用于聲明該服務(wù)中用到的所有權(quán)限,代碼如下

using System.ComponentModel;namespace Demo.Store.Application;/// <summary> /// 權(quán)限列表 /// </summary> public class PermissionLab {[Description("訂單")]public const string ORDER = "Order";[Description("創(chuàng)建訂單")]public const string ORDER_CREATE = $"{ORDER}.Create";[Description("查詢訂單")]public const string ORDER_SELECT = $"{ORDER}.Select";//添加其他權(quán)限 …… }

這里使用常量定義權(quán)限,其中常量的值為權(quán)限碼,常量名稱使用Description特性標(biāo)記。

在Demo.Store.HttpApi.Host項(xiàng)目配置文件appsettings.json中的RemoteServices中添加身份管理服務(wù)地址如下:

"Default": {"BaseUrl": "http://localhost:5000/" },

在Demo.Store.HttpApi.Host項(xiàng)目DemoStoreHttpApiHostModule類OnApplicationInitialization方法中找到?app.UseRouting();?,在其后面添加如下內(nèi)容:

app.UseCusPermissions<PermissionLab>("Store");

這樣我們就可以在聚合服務(wù)層ApplicationService的方法上添加CusPermission用于聲明接口所需要的權(quán)限,例如:

/// <summary> /// 分頁查詢訂單列表 /// </summary> /// <param name="input"></param> /// <returns></returns> /// <exception cref="NotImplementedException"></exception> [CusPermission(PermissionLab.ORDER_SELECT)] public async Task<PagedResultDto<StoreOrderDto>> GetListAsync(PagedAndSortedResultRequestDto input) {var ret = await _orderAppService.GetListAsync(input);return new PagedResultDto<StoreOrderDto>{TotalCount = ret.TotalCount,Items = ObjectMapper.Map<IReadOnlyList<OrderDto>, List<StoreOrderDto>>(ret.Items)}; }

5

補(bǔ)充說明

完成以上步驟后,我們可以在聚合服務(wù)層Admin項(xiàng)目中將身份管理服務(wù)中角色權(quán)限相關(guān)接口封裝并暴露給客戶端調(diào)用,其中注冊(cè)權(quán)限接口僅為聚合服務(wù)層注冊(cè)權(quán)限使用,不建議暴露給客戶端。

這里我只簡(jiǎn)單使用了對(duì)權(quán)限碼自身的校驗(yàn),并未做父子關(guān)系的關(guān)聯(lián)校驗(yàn),在實(shí)際項(xiàng)目中,可以依據(jù)需要進(jìn)行修改或擴(kuò)展。

end

更多精彩

關(guān)注我獲得

總結(jié)

以上是生活随笔為你收集整理的ABP vNext微服务架构详细教程——分布式权限框架(下)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。