【鉴权/授权】一步一步实现一个简易JWT鉴权
微信公眾號(hào):趣編程ACE
關(guān)注可了解.NET日常開(kāi)發(fā)技巧。如需源碼,請(qǐng)公眾號(hào)留言 源碼;
**[如果您覺(jué)得本公眾號(hào)對(duì)您有幫助,歡迎下方掃碼加入群聊]
鑒權(quán)、授權(quán)專(zhuān)題之簡(jiǎn)易鑒權(quán)
我記得作為實(shí)習(xí)生去公司上班的時(shí)候,領(lǐng)導(dǎo)就直接讓我熟悉注冊(cè)、登錄邏輯!!!emm 用他的話來(lái)說(shuō)就是這部分跟業(yè)務(wù)關(guān)聯(lián)性不是很大,你先看看。。。登錄,注冊(cè)是跟業(yè)務(wù)邏輯不咋掛鉤,但是對(duì)框架得熟悉呀!好吧,自此咱就開(kāi)始了搬磚路咯~
安裝需要的Nuget包
1System.IdentityModel.Tokens.Jwt??? 2 3Microsoft.AspNetCore.Authentication? 4 5Microsoft.AspNetCore.Authentication.JwtBearerSystem.IdentityModel.Tokens.Jwt 包含了用于提供創(chuàng)建、序列化、驗(yàn)證Json Web Token的一些類(lèi)型
Microsoft.AspNetCore.Authentication 一個(gè)用來(lái)各種身份驗(yàn)證中間件的Asp.Net Core的基本類(lèi)型
Microsoft.AspNetCore.Authentication.JwtBearer 這是一個(gè)能接受Token的中間件
新建一個(gè)基于.Net6 的web api項(xiàng)目
前言
1public?interface?IAuthenticate 2{ 3????????string?Login(string?userName,string?password);?//?包含一個(gè)登錄方法 4}創(chuàng)建一個(gè)IAuthenticate的接口,里面包含一個(gè)登錄方法,接著便創(chuàng)建一個(gè)實(shí)現(xiàn)類(lèi),實(shí)現(xiàn)Login方法,與此同時(shí)我們需要將這個(gè)接口服務(wù)在容器里面依賴注入一下。
1public?class?AuthenticateImpl?:?IAuthenticate 2{ 3?????public?string?Login(string?userName,?string?password) 4?????{ 5????????..... 6?????}; 7}1//?Program.cs?文件里面依賴注入 2builder.Services.AddSingleton<IAuthenticate>(new?AuthenticateImpl(key));我們知道,在登錄邏輯里面,我們需要對(duì)傳遞過(guò)來(lái)的用戶名和密碼在數(shù)據(jù)庫(kù)里面check一下,只有真真實(shí)實(shí)存在這個(gè)用戶,我們才會(huì)創(chuàng)建并分發(fā)Token。在這里我為了節(jié)省代碼,模擬一下check邏輯
1private?readonly?IDictionary<string,string>?users?=?new?Dictionary<string,string> 2{ 3?????{"person1","aaaaa"}, 4?????{"person2","bbbbb"}, 5};定義一個(gè)用戶字典,key為用戶名,value為密碼 ,此處不考慮密碼編碼加密,一切從簡(jiǎn)。
接著開(kāi)始登錄驗(yàn)證。。。。
創(chuàng)建Token
1public?string?Login(string?userName,?string?password)2{3????????????//?check?用戶真實(shí)存在?4???if(!users.Any(u=>u.Key==userName?&&?u.Value==password))5???{6????????????????return?null;7???}8???//?創(chuàng)建Token9???var?tokenHandle?=?new?JwtSecurityTokenHandler();?//?實(shí)例化一個(gè)?JwtSecurityTokenHandler?對(duì)象 10???var?tokenKey?=?Encoding.ASCII.GetBytes(_key); 11???var?tokenDescriptor?=?new?SecurityTokenDescriptor 12???{ 13???????Subject?=?new?ClaimsIdentity(new?Claim[] 14???????{ 15????????????????????new?Claim(ClaimTypes.Name,userName) 16???????}), 17???????Expires?=?DateTime.UtcNow.AddHours(1), 18???????SigningCredentials?=?new?SigningCredentials( 19????????????new?SymmetricSecurityKey(tokenKey), 20????????????SecurityAlgorithms.HmacSha256Signature) 21???????}; 22???????var?token?=?tokenHandle.CreateToken(tokenDescriptor); 23???????return?tokenHandle.WriteToken(token); 24}詳解
?首先我們需要實(shí)例化一個(gè)JwtSecurityTokenHandler 對(duì)象,這個(gè)對(duì)象呢提供了創(chuàng)建Token的方法,其中一個(gè)就是WriteToken()這個(gè)方法,此方法入?yún)⑹且粋€(gè)SecurityToken對(duì)象,那么如何創(chuàng)建這個(gè)SecurityToken對(duì)象呢?
從上述代碼的22行可以看出,利用CreateToken()這個(gè)方法可以實(shí)現(xiàn),而這個(gè)方法又需要一個(gè)SecurityTokenDescriptor對(duì)象。所以我們將目光移至11行,自此就是一個(gè)生成Token的全部過(guò)程。
開(kāi)啟中間件鑒權(quán)
1//?Asp.net?core?內(nèi)置的鑒權(quán)方案2builder.Services.AddAuthentication(x=>3{4????x.DefaultAuthenticateScheme?=?JwtBearerDefaults.AuthenticationScheme;?//?默認(rèn)是Bearer?方案5????x.DefaultChallengeScheme?=?JwtBearerDefaults.AuthenticationScheme;6}).AddJwtBearer(x=>7{8????x.RequireHttpsMetadata?=false;9????x.SaveToken?=true; 10????x.TokenValidationParameters?=?new?TokenValidationParameters 11????{ 12????????ValidateIssuerSigningKey?=?true, 13????????IssuerSigningKey?=?new?SymmetricSecurityKey(Encoding.ASCII.GetBytes(key)), 14????????ValidateIssuer?=?false, 15????????ValidateAudience?=?false 16????}; 17}); 18 19app.UseAuthentication();?//?使用鑒權(quán)接口訪問(wèn)
我們?cè)贏pi控制器上加上[Authorize()]特性,這樣整個(gè)控制器都需要經(jīng)過(guò)token驗(yàn)證,除非接口上面有[AllowAnonymous]特性修飾
1[Authorize()] 2[ApiController] 3[Route("api/[controller]")] 4public?class?TestJwtController?:?ControllerBase 5{ 6... 7}對(duì)于登錄接口
1[AllowAnonymous]2[HttpPost("login")]3public?IActionResult?Login(User?user)4{5???//?根據(jù)用戶名和密碼,驗(yàn)證用戶并生成Token6???var?token?=_authenticate.Login(user?.UserName,user?.Password);7???if(token?is?null)8???{9?????return?Unauthorized();??//?返回401 10???} 11???return?Ok(token);?//?返回token?登錄成功 12}總結(jié)
以上是生活随笔為你收集整理的【鉴权/授权】一步一步实现一个简易JWT鉴权的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 介绍一款受欢迎的.NET 开源UI库
- 下一篇: Task.Factory.StartNe