為了保護 WebAPI 僅提供合法的使用者存取,有很多機制可以做,透過 JWT (JSON Web Token) 便是其中一種方式,這篇示範如何使用官方所提供的 System.IdentityModel.Tokens.Jwt 擴充套件,處理呼叫 API 的來源是否為合法的使用者身分。
順道一提,要產生 JWT Token 有很多套件可以幫助開發者快速建立,JWT 這個 NuGet 套件就是其中一個,但這裡我使用官方所提供的 System.IdentityModel.Tokens.Jwt 擴充套件來處理,雖然這是官方提供的版本,但寫起來一點也不困難。
Microsoft.IdentityModel.JsonWebTokens是System.IdentityModel.Tokens.Jwt的更新、更快速的版本,具有額外的功能。建議改用 Microsoft.IdentityModel.JsonWebTokens。
建立專案
使用 Visual Studio 2019 建立 ASP.NET Core WebAPI 專案後,首先修改 Startup.cs 中的 ConfigureServices 方法,設定這個 WebAPI 站台要使用哪種方式來驗證 HTTP Request 是否合法,程式碼如下:
1 | public void ConfigureServices(IServiceCollection services) |
這裡我們設定系統在驗證 JWT Token 時,必須要符合以下 4 個條件:
- 相同的 Issuer 設定值
- 相同的 Audience 設定值
- 驗證 Token 有效期限
- 符合對稱式加密的簽章
接者一樣在 Startup.cs 中的 Configure 加入驗證權限用的 Middleware,讓每次進來的 HTTP Request 都會經過此層驗證機制,程式碼如下:
1 | public void Configure(IApplicationBuilder app, IHostingEnvironment env) |
如此一來網站的基本設定就搞定了。
取得 JWT Token
要如何產生 JWT Token 呢?這裡我們建立了一個 AuthController 控制器來產生所需要的 JWT Token,流程如下:
- 身分驗證
- 建立使用者聲明資訊
- 取得加密金鑰
- 建立 JWT Token
身分驗證是你的需求自行實作,驗證後可將取得的使用者資訊(非機敏資訊)包進使用者的 Claim 聲明中,這些資訊將會是 JWT Payload 的一部分,這裡的 Claim 聲明資訊也可以根據你的需求客制增加。
我們知道 JWT 是用三部分 Header、Payload 和 Signature,並使用點(.)將三個部分連結起來成為一個字串,Signature 這部分會是 Header、Payload 加上一組 Secret 做雜湊運算產生出來的,用來驗證整個 JWT 資訊是沒有被竄改過。加密金鑰這段雖然是選用,但還是相當建議加上去,增加安全強度。
接著透過 Microsoft.IdentityModel.JsonWebTokens 這個命名空間底下的 JsonWebTokenHandler 來產生 JWT Token,而 JWT Token 的內容描述則交由 SecurityTokenDescriptor 來組合,在 JWT Token 的內容描述中,請根據需求做調整。
如此一來就可以產生所需要的 JWT Token 了。
1 | [] |
如何使用
使用上非常簡單,只要掛上需要的裝飾器即可,這裡建立了 ValuesController 做測試,分別掛上 [AllowAnonymous] 和 [Authorize],前者是給匿名登入使用,也就是不需要有 JWT Token 也能執行,後者則必須要在 HTTP 的 Authorization Header 必須設定合法的 JWT Bearer Token 才能使用。
1 | [] |
這個驗證裝飾器還可以有很多種玩法,例如根據所建立的驗證 Policy 做驗證,或根據使用者 Claim 聲明的角色做驗證,提供了很大的彈性來處理。
JwtRegisteredClaimNames 屬性說明
在建立使用者的 Claims 聲明時,我們會用到很多 JwtRegisteredClaimNames 結構型別,來取得是先定義好的字串,在 Microsoft.IdentityModel.JsonWebTokens 命名空間中的 JwtRegisteredClaimNames 定義了很多 JWT 會用到的聲明,但官方文件說明相當的少,自行整理了如下:
有些定義的聲明欄位很難找到說明,有找到相關資訊再陸續補充。
程式碼
關於本篇文章完整的程式碼發布於 GitHub:poychang/Demo-WebAPI-Jwt-Auth,請參考裡面的 SimpleJwtAuth 專案。
參考資料:
- JWT JSON Web Token 使用 ASP.NET Core 2.0 Web API 的逐步練習教學與各種情境測試
- aspnet-core-webapi-jwt-auth-example
- ASP.NET Core 中的那些認證中間件及一些重要知識點
- Asp.net Core WebApi 項目使用Jwt進行授權管理和權限驗證
- asp.net core 2.0 web api 基於 JWT 自定義策略授權
- Issuing and authenticating JWT tokens in ASP.NET Core WebAPI - Part I
- 移轉的驗證和身份識別,ASP.NET Core 2.0
- RFC7519 - JSON Web Token - JWT Claims