1. 程式人生 > >【ASP.NET Core學習】使用JWT認證授權

【ASP.NET Core學習】使用JWT認證授權

# 概述 --- 認證授權是很多系統的基本功能 , 在以前PC的時代 , 通常是基於cookies-session這樣的方式實現認證授權 , 在那個時候通常系統的使用者量都不會很大, 所以這種方式也一直很好執行, 隨著現在都軟體使用者量越來越大, 系統架構也從以前垂直擴充套件(增加伺服器效能) -> 水平擴充套件(增加伺服器數量) **cookies-session 工作方式** 客戶端提交使用者資訊 -> 伺服器識別使用者 -> 服務端儲存使用者資訊 -> 返回session-id客戶端 -> 客戶端儲存session-id -> 每次請求cookies帶上session-id 這種方式也不是不能水平擴充套件 , 例如 , session複製/第三方儲存session(資料庫 , Redis) **名詞解析** 認證 : 識別使用者是否合法 授權: 賦予使用者許可權 (能訪問哪些資源) 鑑權: 鑑定許可權是否合法 ## Jwt優勢與劣勢 **優勢** 1. 無狀態 > 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. 新增配置 ```json "JwtOptions": { "Issuer": "https://localhost:5001", "Audience": "https://localhost:5001", "SecurityKey": "1G3l0yYGbOINId3A*ioEi4iyxR7$SPzm" } ``` 3. Jwt Bearer 擴充套件(選項) 4. ConfigureServices ```cs services.AddJwtBearer(options => { options.Issuer = Configuration.GetValue("JwtOptions:Issuer"); options.Audience = Configuration.GetValue("JwtOptions:Audience"); options.SecurityKey = Configuration.GetValue("JwtOptions:SecurityKey"); }); ``` 5. Configure ```cs app.UseAuthentication(); app.UseAuthorization(); ``` 6. add AuthorizeController ```cs //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 新增認證授權 ```cs [ApiController] [Authorize] [Route("[controller]")] public class ApiController : ControllerBase { ... } [HttpPost] [Authorize(Roles = "Admin")] public IActionResult Post() { return Ok(); } ``` --- 轉發請標明出處:[https://www.cnblogs.com/WilsonPan/p/13495936.html](https://www.cnblogs.com/WilsonPan/p/13495936.html) [示例程式碼](https://github.com/WilsonPan/AspNetCoreExamples/tree/master/