ASP.NET Core Web API之Token驗證

在實際開發中,我們經常需要對外提供接口以便客戶獲取數據,由於數據屬於私密信息,並不能隨意供其他人訪問,所以就需要驗證客戶身份。那麼如何才能驗證客戶的什麼呢?今天以一個簡單的小例子,簡述ASP.NET Core Web API開發過程中,常用的一種JWT身份驗證方式。僅供學習分享使用,如有不足之處,還請指正。

 

什麼是JWT?

 

JSON WEB TokenJWT,讀作 [/dʒɒt/]),是一種基於JSON的、用於在網絡上聲明某種主張的令牌(token)。

JWT組成

 

JWT通常由三部分組成: 頭信息(header), 消息體(payload)和簽名(signature)。

  1. 頭信息指定了該JWT使用的簽名算法,HS256 表示使用了 HMAC-SHA256 來生成簽名。
  2. 消息體包含了JWT的意圖
  3. 未簽名的令牌由base64url編碼的頭信息和消息體拼接而成(使用"."分隔),簽名則通過私有的key計算而成。
  4. 最後在未簽名的令牌尾部拼接上base64url編碼的簽名(同樣使用"."分隔)就是JWT了
  5. 典型的JWT的格式:xxxxx.yyyyy.zzzzz

 

JWT應用架構

 

JWT一般應用在分佈式部署環境中,下圖展示了Token的獲取和應用訪問接口的相關步驟:

 

應用JWT步驟

 

1. 安裝JWT授權庫

 

採用JWT進行身份驗證,需要安裝【Microsoft.AspNetCore.Authentication.JwtBearer】,可通過Nuget包管理器進行安裝,如下所示:

 

2. 添加JWT身份驗證服務

 

在啓動類Program.cs中,添加JWT身份驗證服務,如下所示:

builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
        .AddJwtBearer(options =>
        {
            options.TokenValidationParameters = new TokenValidationParameters
            {
                ValidateIssuer = true,
                ValidateAudience = true,
                ValidateLifetime = true,
                ValidateIssuerSigningKey = true,
                ValidIssuer = TokenParameter.Issuer,
                ValidAudience = TokenParameter.Audience,
                IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenParameter.Secret))
            };
        });

 

3. 應用鑑權授權中間件

 

在啓動類Program.cs中,添加鑑權授權中間件,如下所示:

app.UseAuthentication();

app.UseAuthorization();

 

4. 配置Swagger身份驗證輸入(可選)

 

在啓動類Program.cs中,添加Swagger服務時,配置Swagger可以輸入身份驗證方式,如下所示:

builder.Services.AddSwaggerGen(options =>
{
    options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
    {
        Description = "請輸入token,格式爲 Bearer xxxxxxxx(注意中間必須有空格)",
        Name = "Authorization",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.ApiKey,
        BearerFormat = "JWT",
        Scheme = "Bearer"
    });
    //添加安全要求
    options.AddSecurityRequirement(new OpenApiSecurityRequirement {
        {
            new OpenApiSecurityScheme{
                Reference =new OpenApiReference{
                    Type = ReferenceType.SecurityScheme,
                    Id ="Bearer"
                }
            },new string[]{ }
        }
    });
});

注意:此處配置主要是方便測試,如果採用Postman或者其他測試工具,此步驟可以省略。

 

5. 創建JWT幫助類

 

創建JWT幫助類,主要用於生成Token,如下所示:

using DemoJWT.Models;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;

namespace DemoJWT.Authorization
{
    public class JwtHelper
    {
        public static string GenerateJsonWebToken(User userInfo)
        {
            var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(TokenParameter.Secret));
            var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);
            var claimsIdentity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme);
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Sid, userInfo.Id));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Name, userInfo.Name));
            claimsIdentity.AddClaim(new Claim(ClaimTypes.Role, userInfo.Role));
            var token = new JwtSecurityToken(TokenParameter.Issuer,
              TokenParameter.Audience,
              claimsIdentity.Claims,
              expires: DateTime.Now.AddMinutes(120),
              signingCredentials: credentials);

            return new JwtSecurityTokenHandler().WriteToken(token);
        }
    }
}

其中用到的TokenParameter主要用於配置Token驗證的頒發者,接收者,簽名祕鑰等信息,如下所示:

namespace DemoJWT.Authorization
{
    public class TokenParameter
    {
        public const string Issuer = "公子小六";//頒發者        
        public const string Audience = "公子小六";//接收者        
        public const string Secret = "1234567812345678";//簽名祕鑰        
        public const int AccessExpiration = 30;//AccessToken過期時間(分鐘)
    }
}

 

6. 創建Token獲取接口

 

創建對應的AuthController/GetToken方法,用於獲取Token信息,如下所示:

using DemoJWT.Authorization;
using DemoJWT.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.IdentityModel.Tokens.Jwt;

namespace DemoJWT.Controllers
{
    [Route("api/[controller]/[Action]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
        [HttpPost]
        public ActionResult GetToken(User user)
        {
            string token = JwtHelper.GenerateJsonWebToken(user);
            return Ok(token);
        }
    }
}

 

7. 創建測試接口

 

創建測試接口,用於測試Token身份驗證。如下所示:

using DemoJWT.Models;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

namespace DemoJWT.Controllers
{
    [Authorize]
    [Route("api/[controller]/[Action]")]
    [ApiController]
    public class TestController : ControllerBase
    {
        [HttpPost]
        public ActionResult GetTestInfo()
        {
            var claimsPrincipal = this.HttpContext.User;
            var name = claimsPrincipal.Claims.FirstOrDefault(r => r.Type == ClaimTypes.Name)?.Value;
            var role = claimsPrincipal.Claims.FirstOrDefault(r => r.Type == ClaimTypes.Role)?.Value;
            var test = new Test()
            {
                Id = 1,
                Name = name,
                Role = role,
                Author = "公子小六",
                Description = "this is a test.",
            };
            return Ok(test);
        }
    }
}

 

接口測試

 

運行程序,看到公開了兩個接口,如下所示:

 

1. 獲取Token

 

運行api/Auth/GetToken接口,輸入用戶信息,點擊Execute,在返回的ResponseBody中,就可以獲取接口返回的Token

 

 

2. 設置Token

 

在Swagger上方,點擊Authorize,彈出身份驗證配置窗口,如下所示:

3. 接口測試

配置好身份認證信息後,調用/api/Test/GetTestInfo接口,獲取信息如下:

 如果清除掉Token配置,再進行訪問/api/Test/GetTestInfo接口,則會返回401未授權信息,如下所示:

 以上就是ASP.NET Core Web API之Token驗證的全部內容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章