ASP.NET Core使用JWT驗證

Select *
Program
Published in
10 min readJun 27, 2021

JWT(JSON Web Tokens)是一種開放、標準的 RFC 7519 方法,用於在兩方之間以JSON物件安全的傳遞訊息。
本篇將以ASP.NET Core 5.0設定JWT的驗證,以及產生Token與刷新Token,並在呼叫API的時候驗證Token是否有效。
最後,以HttpClient呼叫API與驗證Bearer Token。

JWT的組成

JWT是由三組JSON物件Header、Payload與Signature所組成,這三組JSON物件會各自編碼,物件之間以.做區隔組成一串Token字串。
組合成如Header.Payload.Signature的字串。

實際組成的JWT會如下顯示:

JWT演示

Header

由"alg"與"typ"兩個欄位組成。
alg( algorithm): token加密的演算法,如HMAC、SHA256、RSA。
typ( type): token的類型,基本上就是 JWT。

Header演示

Payload

這裡放的是聲明 (Claim) 內容,也就是用來放傳遞訊息的地方。
JWT 標準公定的Registered claims有七種。

  • iss (issuer):簽發人
  • exp (expiration time):過期時間
  • sub (subject):主題
  • aud (audience):接收人
  • nbf (Not Before):開始生效時間
  • iat (Issued At):簽發時間
  • jti (JWT ID):編號, JWT 的 Id
Payload演示

因為 Payload 傳遞的訊息最後也是透過 Base64 進行編碼,所以是可以被破解的,所以放在Payload的訊息必須為公開、比較不機密的資訊。

Signature

由三部分組成:

  • 以Base64 編碼的Header
  • 以Base64 編碼的Payload
  • secret(密鑰)

Header跟 Payload中間用.來串接,secret 是存放在伺服器端的秘密字串,最後將這三個部分串接在一起的字串,以Header定義的演算法進行加密。

Signature演示

下圖為整個Token產生的流程圖:

JWT Token產生流程圖

JWT實作

以ASP.NET Core 5.0的RESTful API來實作JWT,包含登入驗證、產生Token、驗證Token與Token刷新。

專案採用這裡延續撰寫。
以專案中的API套用JWT驗證機制,來驗證訪問token是否有權限。

會使用到的資料表有三個:

Users資料表:用來儲存使用者帳號密碼。

UserToken資料表:用來儲存Token與RefreshToken。

OrderList資料表:驗證後查詢的資料。

實作步驟

  1. 設定JWT Token驗證
  2. 建立產生JWT Token的方法
  3. 建立RefreshToken的機制
  4. 呼叫API產生Token與驗證
  5. HttpClient呼叫API

設定JWT Token驗證

設定JWT Token的密鑰與註冊驗證的服務。

NuGet下載套件

Microsoft.AspNetCore.Authentication.JwtBearer 
Microsoft.AspNetCore.Identity.EntityFrameworkCore
Microsoft.AspNetCore.Identity.UI

appsettings.json

在appsettings.json中加入JWT的section "JwtConfig"與JWT的密鑰 "Secret"。

"JwtConfig": {
"Secret": "rdqziegmbzhflvkjpvhuadenwoxgpabu"
}
這邊可以使用工具來產生隨機的32位數字串當作密鑰。
(https://www.browserling.com/tools/random-string)

建立密鑰

在專案中新增Configuration資料夾,並新增JwtConfig Class。
用來接收傳遞Secret密鑰。

Startup設定

在Startup.cs的ConfigureServices方法中,加入以下程式碼。
之後在程式中注入JwtConfig,即可取得"appsettings.json"中的"JwtConfig"的值。

接著,繼續在Startup.cs的ConfigureServices方法中,新增驗證配置。
建立TokenValidationParameters,用來驗證客戶端傳過來的token是否合法。並透過AddAuthentication註冊驗證的服務,並設定JWT的驗證配置。

ConfigureServices方法的詳細程式碼如下:

Startup.cs/ConfigureServices()
Startup.cs/ConfigureServices()

然後,在Startup.cs的Configure方法中,app.UseAuthorization()授權之前加入app.UseAuthentication()識別身分。
這樣才能在授權之前,先驗證是否為有效的身分。

Startup.cs/Configure()

ASP.NET Core 中的授權

ASP.NET Core 中的授權是由 AuthorizeAttribute 和其各種參數所控制。 在其最基本的表單中,將 [Authorize] 屬性套用至控制器、動作或 Razor 頁面,會限制對該元件已驗證使用者的存取。

在API接口加入[Authorize]篩選器,限制呼叫時須透過驗證機制。

也可以使用 AllowAnonymous 屬性來允許未經驗證的使用者存取個別動作。

在API接口加入[AllowAnonymous]篩選器,不用驗證也能呼叫

建立產生JWT Token的方法

新增Mehod來檢核登入帳號,並產生JWT Token。

建立驗證的回傳訊息

在Configuration資料夾中,建立新class命名AuthResult,用來回覆驗證後的訊息。

Configuration/AuthResult.cs

建立DTO

建立DTO(data transfer objects),在Models資料夾裡新增DTOs資料夾。
並在DTOs資料夾中新增兩個資料夾Requests跟Responses。

Models/DTOs

在Models/DTOs/Requests中,新增UserLoginRequest.cs,做為登入的Request。

Models/DTOs/Requests/UserLoginRequest.cs

在Models/DTOs/Response中,新增UserLoginResponse.cs,並直接繼承AuthResult.cs。

Models/DTOs/Response/UserLoginResponse.cs

AuthManagementController

在Controllers資料夾中,新增AuthManagementController.cs,並注入JwtConfig與MyDBContext。

Controllers/AuthManagementController.cs

新增Method來產生JWT Token

新增GenerateJwtToken方法,用來產生JWT Token。

程式碼如下:

AuthManagementController.cs/GenerateJwtToken()

新增Method做為登入用

新增Login方法,做為登入的API接口。在驗證帳號、密碼後,呼叫GenerateJwtToken方法產生JWT Token並回傳資訊。

程式碼如下:

AuthManagementController.cs/Login()

建立RefreshToken的機制

新增Mehod,驗證Token與RefreshToken後,建立新的Token並回傳。

建立DTO

Models/DTOs/Requests新增TokenRequest.cs,做為刷新token的Request。

Models/DTOs/Requests/TokenRequest.cs

AuthManagementController

注入TokenValidationParameters。

AuthManagementController.cs

新增Method驗證並重新產生Token

新增VerifyAndGenerateToken方法,在驗證Token參數後,呼叫GenerateJwtToken方法,產生新Token並回傳。

程式碼如下:

AuthManagementController.cs/VerifyAndGenerateToken()

新增Method做為刷新Token用

新增RefreshToken方法,做為刷新Token的API接口。
呼叫VerifyAndGenerateToken方法來驗證輸入的Token參數與回傳刷新的Token。

程式碼如下:

AuthManagementController.cs/RefreshToken()

呼叫API產生Token與驗證

執行傳案後,以Postman呼叫/api/AuthManagement/Login,來登入並取得Token與RefreshToken。

Body內容為:

執行畫面:

若要刷新產生新的Token,呼叫/api/AuthManagement/RefreshToken,來刷新Token。

執行畫面:

呼叫掛有[Authorize]驗證的API,在Postman的Authorization中,選擇Tyep為Bearer Token,並輸入Token。

執行畫面:

HttpClient呼叫API

在C#中使用HttpClient呼叫API時,設定Header的驗證Token可使用:

--

--