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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)

發布時間:2023/12/4 asp.net 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

權限管控對于一個系統來說是非常重要的,最熟悉不過的是菜單權限和數據權限,上一節通過Jwt實現了認證,接下來用它實現接口權限的驗證,為什么不是菜單權限呢?對于前后端分離而言,稱其為接口權限感覺比較符合場景(我是這么理解的);數據權限牽涉到具體業務,這里就不說啦!

正文

對于一些比較簡單的系統,訪問角色可能只有固定的幾種,比如一些產品管理系統,通常只有管理員、維護員、用戶三種權限,管理員擁有整個系統的權限,維護員只能訪問產品維護相關頁面和操作,用戶只能訪問產品的一些信息,如果類似這種情況,可以直接指定角色的方式進行權限管控,如下:

案例代碼直接使用上一節的項目,借用上次認證那塊代碼(偷懶太明顯~~~),如果沒看上一篇的小伙伴,去瞅瞅認證那塊內容(跟我一起學.NetCore之WebApi接口裸奔有風險(Jwt)),隨便敲敲代碼,這節要用(別說我,我是有苦衷的,想讓小伙伴多擼代碼~~~);如果只是想熟悉知識點,也可以繼續往下看的,不廢話,直接開始:

注:[Authorize]加在控制器上時,該控制器下所有的接口都受保護;

為了方便測試,如上圖所示,增加一個產品控制器,針對不同人員模擬了三個接口,因為接口受到保護,只能通過獲取到的Token才能正常訪問,這里就不截圖演示了。Token調用User中的Login接口獲取,詳細請參考(跟我一起學.NetCore之WebApi接口裸奔有風險(Jwt))。哎呀,還是上個生成Token的代碼圖:

下面將三個接口指定為不同角色訪問,然后運行訪問如下:

通過運行測試可知,當增加了對應角色要求之后,盡快Token驗證正確,也不能正常調用接口,返回403禁止訪問。已經為接口指定了角色,那要如何才能正常調用呢?其實只要在生成Token的時候指定對應角色即可正常訪問對應角色的接口,如下代碼優化:

如上運行所示,在生成Token時指定了角色為Admin,則這個Token只能訪問指定角色為Admin的接口,其他接口是不能訪問的。如需要訪問其他接口,同樣需要在生成Token的時候添加對應的角色,如下:

運行效果這里就不截圖演示了,小伙伴們自己試試。

看到這,小伙伴們肯定會問,管理員角色肯定是所有接口都能訪問,拿到了Token接下來該咋辦,每個接口都加管理員角色對應的特性嗎?對于多個角色訪問同一個接口的情況,一般會為授權定義策略來實現,如下:

運行效果如下:

小注意點:

  • 多個角色或運算:多個角色只要有其中一個就可以訪問;

  • 多個角色且運算:同時得有多個角色才能訪問接口;

到這,相信小伙伴已經忍不住要問:不管是角色還是策略的方式,角色都寫死了,如果角色動態分配權限咋搞??是的,上面的方式只適合對權限管控比較簡單的項目,絕大數的項目權限肯定是動態分配的,即根據需求,可以針對用戶進行訪問權限配置,所以接下來就說說這塊咋搞。

這次增加的代碼稍微有點多,代碼都有注釋,另外跟著我標注的步驟走,絕對No Problem:

通過以上步驟就完成動態權限的驗證了,是不是很給力,這里需要注意一下幾個點:

  • 后續用到IHttpContextAccessor需要進行注冊;


  • 用戶ID在登錄的時候要放入Payload中,后續權限驗證時要用;

  • API中使用的策略名稱要和定義的一致;

以上案例演示中,在登錄的時候模擬權限數據存入內存,對于一些用戶數據不大的項目,這種方式還不錯,但是對于用戶數量比較大或者分布式部署的項目,建議將權限數據存入Redis等緩存數據庫中,存取統一的同時也能減少對數據庫的訪問壓力,總不能每次請求過來都從數據庫中獲取權限數據進行校驗。

小知識點:

  • 通過獲取用戶時,訪問的接口必須要有Authorize特性,否則只能通過自己解析Token獲取;

  • 如果在統一受保護的控制器中,有個別接口不需要權限驗證,可以為其標注AllowAnonymous特性即可;

校驗權限邏輯的完整代碼如下:

using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks;namespace SwaggerDemo.Permission {/// <summary>/// 權限處理的關鍵類/// </summary>public class PermissionHandler : AuthorizationHandler<PermissionRequirement>{/// <summary>/// 通過IHttpContextAccessor可以獲取HttpContext相關信息,但一定要注冊服務/// </summary>private readonly IHttpContextAccessor _accessor;/// <summary>/// 用于判斷請求是否帶有憑據和是否登錄/// </summary>public IAuthenticationSchemeProvider Scheme { get; set; }/// <summary>/// 構造函數注入/// </summary>public PermissionHandler(IHttpContextAccessor accessor,IAuthenticationSchemeProvider scheme){this._accessor = accessor;Scheme = scheme;}protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement){try{//拿到HttpContext就無所不能啦var httpContext = _accessor.HttpContext;//判斷資源數據中權限列表中是否有權限if (!requirement.Permissions.Any()){//沒有直接返回無權限,也可以重新獲取權限,實現不退出重新登錄就可獲取最新權限context.Fail();}//判讀請求是否擁有憑據,即是否登錄var defaultAuthenticate = await Scheme.GetDefaultAuthenticateSchemeAsync();if (defaultAuthenticate == null){context.Fail();}var result = await httpContext.AuthenticateAsync(defaultAuthenticate.Name);//不為空代表登錄成功,為空登錄失敗if (result?.Principal != null){// 獲取生成Token時放在payload里的userIdstring userId = _accessor.HttpContext.User.FindFirst("userId").Value;// 獲取當前請求的地址string requestUrl = httpContext.Request.Path.Value.ToLower();// 從權限表中查找當前用戶是否有當前請求地址的權限var permission = requirement.Permissions.FirstOrDefault(a => a.Url.ToLower() == requestUrl && a.UserId == userId);// 如果沒找到,代表沒有權限if (permission == null){context.Fail();}// 如果找到,就繼續往下執行context.Succeed(requirement);}else{// 獲取不到對應值就返回無權限context.Fail();}}catch (Exception ex){context.Fail();}}} }

總結

關于權限驗證這塊之前大多都是在MVC的授權過濾器中進行完成的,?本來想在說過濾器那塊一起說說權限驗證的,但感覺關于Jwt的放在一塊比較合適。關于Jwt其實還有一個比較關鍵的點,就是對于Token的處理問題,比如刷新Token、手動失效Token等,這塊后續單獨整理一篇內容分享。下次先說說過濾器的執行順序。

關于代碼,其實現在在寫案例的時候感覺已經開始復雜了,后面整理整理會放在github上,如果急需的可以私下找我,我單獨發給小伙伴。

一個被程序搞丑的帥小伙,關注"Code綜藝圈",識別關注跟我一起學~~~

擼文不易,莫要白瞟,三連走起~~~~

總結

以上是生活随笔為你收集整理的跟我一起学.NetCore之熟悉的接口权限验证不能少(Jwt)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。