1. 程式人生 > 實用技巧 >NetCore自定義授權記錄

NetCore自定義授權記錄

之前做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 class
RoleMenu { /// <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,批量匯入介面說明,然後選單維護只要選擇這些介面就好,不過製作選單還是很麻煩,需要對按鈕操作還需要指定上級,若博友們在實際生產中有更好的實現方式,懇請留言下,萬分感謝!!

劇終!!!