.Net Core JWT 動態設定介面與許可權

以往清泉發表於2020-12-05

通過上一篇.Net Core官方的 JWT 授權驗證學習到了JWT的授權。可以發現一個問題,就是如果每個介面可以使用的角色都是寫死的,這樣如果有所修改會非常麻煩,雖然用policy可以一定程度上緩解,但是還是不能根治。

所以,就需要動態的設定介面與許可權,由我們自己來處理。

我們先建立一個類 PermissionRequirement 繼承介面 IAuthorizationRequirement,這個類是介面與角色的關係類,裡面的欄位可以按自己的需要新增。

public class PermissionRequirement : IAuthorizationRequirement
{
  public string Url { get; set; }
  public List<string> Roles { get; set; }
}

之後建立一個處理類 PermissionHandler 繼承 AuthorizationHandler 類,來處理請求中介面和角色許可權的關係。

public class PermissionHandler : AuthorizationHandler<PermissionRequirement>
{
    protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement)
    {
        //模擬從資料庫或者快取中取出的訪問url的許可權資料
        var roles = new List<PermissionRequirement>();
        roles.Add(new PermissionRequirement() { Url = "weatherforecast", Roles = new List<string>() { "system" } });
        //JWT的token中的宣告等資訊都會自動解析在context中
        var resource = ((Microsoft.AspNetCore.Routing.RouteEndpoint)context.Resource).RoutePattern;
        foreach(var t in context.User.Identities)
        {
            foreach(var claim in t.Claims)
            {
                //通過Type可以判斷宣告的型別,這裡處理role的宣告獲取角色資訊
                if(claim.Type == ClaimTypes.Role)
                {
                    if(roles.Exists(x => x.Roles.Exists(role => role == claim.Value) && x.Url == resource.RawText.ToLower()))
                    {
                        context.Succeed(requirement);
                        return;
                    }
                }
            }
        }
        context.Fail();
        return;
    }
}

在 Startup 類中其他都不變,只需要新增在 ConfigureServices 方法中新增上如下程式碼即可,通過以來注入 PermissionHandler 類來替換成我們的處理類。

services.AddAuthorization(option => {
    //option.AddPolicy("adminOrSystem", policy => policy.RequireRole("admin", "system"));
    option.AddPolicy("Permission", policy => policy.AddRequirements(permissionRequirement));
});
services.AddSingleton<IAuthorizationHandler, PermissionHandler>();
// 將授權必要類注入生命週期內
services.AddSingleton(permissionRequirement);

最後只需要在介面或控制器上新增 [Authorize(Policy = "Permission")] 就可以啦,只要有該特性的介面訪問都會走我們的處理類 PermissionHandler 判斷介面和角色的關係,從而實現了動態設定介面和許可權的要求。

我這裡的程式碼比較的簡陋,最低限度的實現,可以自己根據需求完善。也可以看下面的參考文章。

參考文章:

ASP.NET Core 使用 JWT 自定義角色/策略授權需要實現的介面

從壹開始前後端分離[.NetCore] 37 ║JWT完美實現許可權與介面的動態分配

 

相關文章