.Net Core手撸一个基于Token的权限认证
說明
權(quán)限認(rèn)證是確定用戶身份的過程。可確定用戶是否有訪問資源的權(quán)力
今天給大家分享一下類似JWT這種基于token的鑒權(quán)機(jī)制
基于token的鑒權(quán)機(jī)制,它不需要在服務(wù)端去保留用戶的認(rèn)證信息或者會話信息。這就意味著基于token認(rèn)證機(jī)制的應(yīng)用,不需要去考慮用戶在哪一臺服務(wù)器登錄了,這就為應(yīng)用的擴(kuò)展提供了便利。
流程上是這樣的:
?用戶使用用戶名密碼來請求服務(wù)器?服務(wù)器進(jìn)行驗證用戶的信息?服務(wù)器通過驗證發(fā)送給用戶一個token?客戶端存儲token,并在每次請求時附送上這個token值?服務(wù)端驗證token值,并返回數(shù)據(jù)
那我今天給大家手?jǐn)]一個類似Jwt的權(quán)限認(rèn)證
演示
新建一個授權(quán)篩選器繼承IAuthorizationFilter
public?class?ApiAuthorize?:?IAuthorizationFilter{}新建一個需要應(yīng)用授權(quán)的特性和允許未通過身份驗證也可以訪問的特性
public?class?MyAuthentication:Attribute,?IFilterMetadata{}public?class?MyNoAuthentication?:?Attribute,?IFilterMetadata{}我們需要在我們的授權(quán)過濾器判斷請求頭是否帶有應(yīng)用授權(quán)的特性和允許未通過身份驗證也可以訪問的特性,如果有允許未通過身份驗證也可以訪問的特性就直接進(jìn)入下一個管道 ,如果帶有應(yīng)用授權(quán)的特性則進(jìn)行token判斷
public?class?ApiAuthorize?:?IAuthorizationFilter{public?void?OnAuthorization(AuthorizationFilterContext?context){if?(context.Filters.Contains(new?MyNoAuthentication())){return;}var?authorize?=?context.HttpContext.Request.Headers["MyAuthentication"];if?(string.IsNullOrWhiteSpace(authorize)){context.Result?=?new?JsonResult("請求authorize不能為空");return;}if?(!MemoryCacheHelper.Exists(authorize)){context.Result?=?new?JsonResult("無效的授權(quán)信息或授權(quán)信息已過期");return;}}}可能有的小伙伴發(fā)現(xiàn)了,那我們Token怎么去存取呢,一般的方案是使用Cache來處理,這里就不做過多討論了,有想了解的小伙伴可以看我上一篇文章!
CacheHelper代碼
public?class?MemoryCacheHelper{public?static?MemoryCache?_cache?=?new?MemoryCache(new?MemoryCacheOptions());///?<summary>///?驗證緩存項是否存在///?</summary>///?<param?name="key">緩存Key</param>///?<returns></returns>public?static?bool?Exists(string?key){if?(key?==?null){throw?new?ArgumentNullException(nameof(key));}return?_cache.TryGetValue(key,?out?_);}///?<summary>///?獲取緩存///?</summary>///?<param?name="key">緩存Key</param>///?<returns></returns>public?static?object?Get(string?key){if?(key?==?null){throw?new?ArgumentNullException(nameof(key));}if?(!Exists(key))throw?new?ArgumentNullException(nameof(key));return?_cache.Get(key);}///?<summary>///?添加緩存///?</summary>///?<param?name="key">緩存Key</param>///?<param?name="value">緩存Value</param>///?<param?name="expiresSliding">滑動過期時長(如果在過期時間內(nèi)有操作,則以當(dāng)前時間點延長過期時間)</param>///?<param?name="expiressAbsoulte">絕對過期時長</param>///?<returns></returns>public?static?bool?AddMemoryCache(string?key,?object?value){if?(key?==?null){throw?new?ArgumentNullException(nameof(key));}if?(value?==?null){throw?new?ArgumentNullException(nameof(value));}_cache.Set(key,?value,new?MemoryCacheEntryOptions(){SlidingExpiration?=?new?TimeSpan(0,?0,?10),Priority?=?CacheItemPriority.NeverRemove,AbsoluteExpiration?=?DateTime.Now.AddMinutes(1)});return?Exists(key);}}權(quán)限認(rèn)證代碼基本完成了,我們回到剛剛的流程
用戶使用用戶名密碼來請求服務(wù)器, 服務(wù)器進(jìn)行驗證用戶的信息,服務(wù)器通過驗證發(fā)送給用戶一個token
對于一個商用軟件來說絕大多數(shù)接口都需要應(yīng)用授權(quán)后才能使用,所以我們注冊到全局, 在StartUp類里面注冊
public?void?ConfigureServices(IServiceCollection?services){services.AddControllers(o=>{o.Filters.Add<ApiAuthorize>();o.Filters.Add<MyAuthentication>();});}Token生成原理我這里就不做過多解讀了,本例子使用AES加密生成Token 在我們服務(wù)端的請求token接口加上允許未通過身份驗證也可以訪問的特性,然后頒發(fā)一個Token
[HttpGet("GetToken")] [MyNoAuthentication] public?IActionResult?GetToken(string?UserCode) {string?token=??AESEncrypt.Encrypt(UserCode);MemoryCacheHelper.AddMemoryCache(token,?User);eturn?Ok(token); }使用Postman請求生成token,如圖所示
然后我們在新增一個需要應(yīng)用授權(quán)的接口,由于我們注冊了全局的應(yīng)用授權(quán)特性就不需要在帶上該特性了
[HttpGet("GetUserInformation")]public?IActionResult?GetUserInformation(){return?Ok(new?{?Name="123",Age=18,Sex="性別"});}不帶token使用postman請求該接口,如圖所示
帶上token使用postman請求該接口,如圖所示
通過剛才的例子我們清楚了解了權(quán)限認(rèn)證的過程,今天的介紹就到此結(jié)束了!
最后大家如果喜歡我的文章,還麻煩給個關(guān)注并點個贊, 希望net生態(tài)圈越來越好!
總結(jié)
以上是生活随笔為你收集整理的.Net Core手撸一个基于Token的权限认证的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WPF 使用DrawingVisual绘
- 下一篇: .NET 中密封类的性能优势