ASP.NET Core學習之使用JWT認證授權詳解
概述
認證授權是很多系統的基本功能,在以前PC的時代,通常是基於cookies-session這樣的方式實現認證授權,在那個時候通常系統的使用者量都不會很大,所以這種方式也一直很好執行,隨著現在都軟體使用者量越來越大,系統架構也從以前垂直擴充套件(增加伺服器效能) -> 水平擴充套件(增加伺服器數量)
cookies-session 工作方式
客戶端提交使用者資訊 -> 伺服器識別使用者 -> 服務端儲存使用者資訊 -> 返回session-id客戶端 -> 客戶端儲存session-id -> 每次請求cookies帶上session-id
這種方式也不是不能水平擴充套件,例如,session複製/第三方儲存session(資料庫,Redis)
名詞解析
認證 : 識別使用者是否合法
授權: 賦予使用者許可權 (能訪問哪些資源)
鑑權: 鑑定許可權是否合法
Jwt優勢與劣勢
優勢
無狀態
token 儲存身份驗證所有資訊,服務端不需要儲存使用者身份驗證資訊,減少服務端壓力,服務端更容易水平擴充套件,由於無狀態,又會導致它最大缺點,很難登出
2、支援跨域訪問
Cookie是不允許垮域訪問的,token支援
3、跨語言
基於標準化的 JSON Web Token (JWT),不依賴特定某一個語言,例如生成對Token可以對多個語言使用(Net,Java,PHP ...)
劣勢
1、Token有效性問題
後臺很難登出已經發布的Token,通常需要藉助第三方儲存(資料庫/快取) 實現登出,這樣就會失去JWT最大的優勢
2、佔頻寬
Token長度(取決存放內容) 比session_id大,每次請求多消耗頻寬,token只存必要資訊,避免token過長
3、需要實現續簽
cookies - session 通常是框架已經實現續簽功能,每次訪問把過期時間更新,JWT需要自己實現,參考OAuth2重新整理Token機制實現重新整理Token
4、消耗更多CPU
每次請求需要對內容解密和驗證簽名這兩步操作,典型用時間換空間
只能根據自身使用場景決定使用哪一種身份驗證方案,沒有一種方案是通用的,完美的
AspNetCore整合Jwt認證
1、新增包
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
2、新增配置
"JwtOptions": { "Issuer": "https://localhost:5001","Audience": "https://localhost:5001","SecurityKey": "1G3l0yYGbOINId3A*ioEi4iyxR7$SPzm" }
3、Jwt Bearer 擴充套件(選項)
public static AuthenticationBuilder AddJwtBearer(this IServiceCollection services,Action<JwtOptions> configureOptions) { if (configureOptions == null) throw new ArgumentNullException(nameof(configureOptions)); var jwtOptions = new JwtOptions() { Issuer = "Jwt Authentication",Audience = "Wilson Pan Web Api",}; // set customs optoins configureOptions(jwtOptions); // update Options services.PostConfigure<JwtOptions>(options => { options.Issuer = jwtOptions.Issuer; options.Audience = jwtOptions.Audience; options.SecurityKey = jwtOptions.SecurityKey; }); return services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme) .AddJwtBearer(options => { options.TokenValidationParameters = new TokenValidationParameters() { ValidIssuer = jwtOptions.Issuer,ValidAudience = jwtOptions.Audience,ValidateIssuer = true,ValidateLifetime = true,ValidateIssuerSigningKey = true,IssuerSigningKey = jwtOptions.SymmetricSecurityKey }; }); }
4、ConfigureServices
services.AddJwtBearer(options => { options.Issuer = Configuration.GetValue<string>("JwtOptions:Issuer"); options.Audience = Configuration.GetValue<string>("JwtOptions:Audience"); options.SecurityKey = Configuration.GetValue<string>("JwtOptions:SecurityKey"); });
5、Configure
app.UseAuthentication(); app.UseAuthorization();
6、add AuthorizeController
//define claim var claims = new Claim[] { new Claim(ClaimTypes.Name,username),new Claim(ClaimTypes.Email,$"{username}@github.com"),new Claim(ClaimTypes.Role,username == "WilsonPan" ? "Admin" : "Reader"),new Claim(ClaimTypes.Hash,JwtHashHelper.GetHashString($"{username}:{password}:{System.DateTime.Now.Ticks}")),}; //define JwtSecurityToken var token = new JwtSecurityToken( issuer: _jwtOptions.Issuer,audience: _jwtOptions.Audience,claims: claims,expires: System.DateTime.Now.AddMinutes(5),signingCredentials: _jwtOptions.SigningCredentials ); // generate token var result = new JwtSecurityTokenHandler().WriteToken(token);
7、Contrller/Action 新增認證授權
[ApiController] [Authorize] [Route("[controller]")] public class ApiController : ControllerBase { ... } [HttpPost] [Authorize(Roles = "Admin")] public IActionResult Post() { return Ok(); }
Rest Client
dotnet run
1、認證介面
@host = https://localhost:5001 # @name token POST {{host}}/Authorize HTTP/1.1 Content-Type: application/x-www-form-urlencoded #username=Wilson&password=123456 # admin username=WilsonPan&password=123456
2、需要授權介面
### required authorize GET {{host}}/api HTTP/1.1 Authorization: Bearer {{token.response.body.*}}
3、需要管理員角色介面
### required authorize POST {{host}}/api HTTP/1.1 Authorization: Bearer {{token.response.body.*}}
示例程式碼
總結
到此這篇關於ASP.NET Core學習之使用JWT認證授權的文章就介紹到這了,更多相關ASP.NET Core用JWT認證授權內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!