NetCore自定義授權記錄
阿新 • • 發佈:2020-12-07
之前做MVC專案的選單授權,都是通過Filter去校驗Url是否可訪問action,大體思路:
1.需要驗證的controller 或action 用繼承特性[AuthorizeAttribute]標記
2.使用者登入獲取可訪問的選單集合記錄快取
3.在特性方法中 校驗 集合快取是否有當前action,確認是否可訪問。
現Core/.Net5大火(雖然學習有點晚,但是還得學習啊o(╥﹏╥)o),WebAPI的許可權設定沒玩過,在研究官方文件,結合部落格大佬們(關注了好幾個MVP)的博文,記錄一個實現思路
1.採用的是自定義策略模式,原因:固定role和claim的授權對開發不夠靈活,自定義策略可以自己寫程式碼校驗是否授權通過, 官方文件介紹
2.實現需要的幾個類和介面
1)自定義校驗類需要實現IAuthorizationRequirement,此介面只是標記作用,然後可以自定義屬性,我的實現如下
public class CustomRequirement: IAuthorizationRequirement { /// <summary> /// 全部許可權集合 /// </summary> public List<RoleMenu> PowerList { get; set; } }
public classRoleMenu { /// <summary> /// 選單路徑 /// </summary> public string Url { get; set; } /// <summary> /// 角色ID /// </summary> public string RoleId { get; set; } }
2)增加處理邏輯 ,需要實現抽象介面AuthorizationHandler<CustomRequirement> 泛型類是我們剛實現IAuthorizationRequirement
public class MyAuthorHandle : AuthorizationHandler<CustomRequirement> { private readonly IHttpContextAccessor _httpContextAccessor; public MyAuthorHandle(IHttpContextAccessor httpContextAccessor) { _httpContextAccessor = httpContextAccessor; } protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, CustomRequirement requirement) { var hasroute = requirement.PowerList.FirstOrDefault(t => t.Url.ToLower() == _httpContextAccessor.HttpContext.Request.Path.Value.ToLower()//校驗路徑 && context.User.Claims.FirstOrDefault(m=>m.Type==ClaimTypes.Role&&m.Value== t.RoleId)!=null//檢視當前使用者的Role是否被包含 ); if (hasroute != null) { //可以訪問 context.Succeed(requirement); } //預設是Fail return Task.CompletedTask; } }
3)呼叫,需要在Starup的鑑權服務中新增以下程式碼
services.AddSingleton<IAuthorizationHandler, MyAuthorHandle>(); services.AddSingleton<CustomRequirement>(); services.AddAuthorization(option => { //自定義策略 option.AddPolicy("CustomPolicy", policy => { var customRequirement = new CustomRequirement() { PowerList = new List<RoleMenu>() }; //此處需要從資料庫獲取許可權集合,並注入單例,這樣就可以在許可權修改後對此單例直接修改許可權集合 //測試資料 customRequirement.PowerList.Add( new RoleMenu() { RoleId = "ceshi", Url = "/home/Index" } ); policy.Requirements.Add(customRequirement); }); });
4)Contoller 使用,對需要選單校驗的action或Contoller 可以新增[Authorize(Policy = "CustomPolicy")]
此實現方式,需要維護大量介面,先有個想法,在開發階段制定個標準特性或效仿Swagger 讀取到所有介面,製作成一個SQL,批量匯入介面說明,然後選單維護只要選擇這些介面就好,不過製作選單還是很麻煩,需要對按鈕操作還需要指定上級,若博友們在實際生產中有更好的實現方式,懇請留言下,萬分感謝!!
劇終!!!