天天看点

ASP.NET Core 6中如何实现JWT认证

作者:码上尽宝

JSON Web Tokens (JWT) 是一种轻量级的身份认证和授权机制,在实际的 Web 应用程序中得到了广泛应用。在 ASP.NET Core 中,可以使用 Authentication 中间件和 JWT 来实现基于 Token 的身份认证和授权功能。 在文中,我将介绍如何使用 Authentication 中间件实现 JWT 身份认证和授权。欢迎大家一起学习。本文主要分两部分,先简单介绍什么是JWT,然后基于.NET6 实现一个JWT的认证demo,带领大家一起了解JWT实现过程。

ASP.NET Core 6中如何实现JWT认证

一、什么是 JWT

JWT(JSON Web Token)是一种基于 JSON 的轻量级开放标准选项,用于在网络应用程序间安全、可靠地传递信息。JWT 的主要优势是服务器不需要维护会话状态或其他维护状态信息的方式,而是仅在接收到 JWT 时检查是否有效即可确定用户访问权限。JWT 通常用于身份验证和授权,JWT token 不仅包含了自身的信息,还有所需考虑的加密签名密钥信息等。

WT Token 由三部分组成,基本结构如下:

1、Header 部分包含两个主要部分,分别是:

  • 声明 Token 类型:这里使用的是 JWT
  • 声明所使用的加密算法:例如,HMAC SHA256 或 RSA。

2、Payload 部分也被称为 JWT Claim,是一组由键值对组成的信息,例如用户 ID、发行人、过期时间等等。它可以携带关于身份验证信息和其他有用信息,但不应该包含敏感信息。

3、Signature 部分包含了前面的两个部分所组成的一个令牌,以及一份秘密密钥,用于加密头和载荷。这样,服务器就可以使用签名密钥验证令牌的完整性。

JWT 有如下特点:

  • 具有轻量、安全、可靠、易于实现等优势。
  • JWT 存储在客户端,不需要服务器存储会话状态。
  • JWT 是有序的、基于 JSON Web Tokens,所以易于传输和解析。
  • JWT 支持各种加密签名算法。

二、.NET6 实现JWT 实例

  1. 首先,在 ASP.NET Core 应用程序中添加 Microsoft.AspNetCore.Authentication.JwtBearer 包,使用 Package Manager 工具或使用 NuGet 搜索该包。
  2. 在 Startup.cs 文件 ConfigureServices() 方法中添加以下代码段来配置 JWT 授权认证中间件选项
var issuer = builder.Configuration["JwtAuthorization:Issuer"];
var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JwtAuthorization:SigningKey"]));
var encryptionAlgorithm = builder.Configuration["JwtAuthorization:EncryptionAlgorithm"];

// Jwt 授权认证配置
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
{
    options.IncludeErrorDetails = true;
    options.TokenValidationParameters = new TokenValidationParameters
    {
        ValidateIssuer = true,
        ValidateAudience = true,
        ValidateLifetime = true,
        ValidateIssuerSigningKey = true,
        ValidIssuer = issuer,
        ValidAudience = issuer,
        IssuerSigningKey = signingKey
    };
});           

其中appsettings.json 文件中添加以下配置

"JwtAuthorization": {
    "Issuer": "http://www.ppfbh.com",
    "EncryptionAlgorithm": "HS256",
    "SigningKey": "597530a4-92ab-4bd2-a333-9fdedcc5ce23"
  },           

这里的 "Issuer" 用于指定 Token 颁发者,"EncryptionAlgorithm" 用于指定使用的加密算法,"SigningKey" 是用于签署和验证 Token 的密钥。请根据您的需要修改配置项。

3.在builder.Build()后面增加认证和授权。

app.UseAuthentication();
app.UseAuthorization();           

4、创建授权 Token 的方法代码

private string GenerateToken(string userId, string role)
        {
            var payload = new JwtAuthorizationPayload
            {
                UserId = userId,
                Role = role
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtAuthorization:SigningKey"]));
            var encryptionAlgorithm = _configuration["JwtAuthorization:EncryptionAlgorithm"];
            var tokenIssuer = _configuration["JwtAuthorization:Issuer"];

            var securityToken = new SecurityTokenDescriptor
            {
                Issuer = tokenIssuer,
                Audience = tokenIssuer,
                Subject = new ClaimsIdentity(new List<Claim>
                {
                    new Claim(ClaimTypes.NameIdentifier, payload.UserId),
                    new Claim(ClaimTypes.Role, payload.Role)
                }, "Bearer"),
                Expires = DateTime.UtcNow.AddMinutes(30),
                SigningCredentials = new SigningCredentials(signingKey, encryptionAlgorithm)
            };

            var token = tokenHandler.CreateToken(securityToken);

            return tokenHandler.WriteToken(token);
        }           

三、测试验证

新建一个UserController 控制器,在控制器方法或动作中添加 [Authorize] 特性,指示需要身份认证和授权才能访问此资源。代码如下:

[ApiController]
    [Route("api/[controller]")]
    public class UserController : ControllerBase
    {
        private readonly IConfiguration _configuration;

        public UserController(IConfiguration configuration)
        {
            _configuration = configuration;
        }

        [HttpPost("login")]
        public IActionResult Login(string username, string password)
        {
            // 模拟登入,返回token
            var user = CheckUserFromDB(username, password);
            var token = GenerateToken(user.Id, user.Role);
            return Ok(new { token });
        }

        [Authorize(Roles = "Admin_Test")]
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new[] { "value1", "value2" };
        }

        [Authorize(Roles = "Admin_Menu")]
        [HttpGet]
        [Route("menu")]
        public IEnumerable<string> Menu()
        {
            return new[] { "value1", "value2" };
        }

        private User CheckUserFromDB(string username, string password)
        {
            return new User { Id = "1001", Role = "Admin_Test" };
        }

        private string GenerateToken(string userId, string role)
        {
            var payload = new JwtAuthorizationPayload
            {
                UserId = userId,
                Role = role
            };

            var tokenHandler = new JwtSecurityTokenHandler();
            var signingKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["JwtAuthorization:SigningKey"]));
            var encryptionAlgorithm = _configuration["JwtAuthorization:EncryptionAlgorithm"];
            var tokenIssuer = _configuration["JwtAuthorization:Issuer"];

            var securityToken = new SecurityTokenDescriptor
            {
                Issuer = tokenIssuer,
                Audience = tokenIssuer,
                Subject = new ClaimsIdentity(new List<Claim>
                {
                    new Claim(ClaimTypes.NameIdentifier, payload.UserId),
                    new Claim(ClaimTypes.Role, payload.Role)
                }, "Bearer"),
                Expires = DateTime.UtcNow.AddMinutes(30),
                SigningCredentials = new SigningCredentials(signingKey, encryptionAlgorithm)
            };

            var token = tokenHandler.CreateToken(securityToken);

            return tokenHandler.WriteToken(token);
        }
    }           

如代码所示:我们建立了三个方法

1、Login 模拟用户登入,生成Token;

2、Get 模拟正确的用户API;

3、Menu 模拟认证错误的API;

4、结果展示

1、利用Postman进行接口调试,首先方法登入接口。

ASP.NET Core 6中如何实现JWT认证

产生一个JWTtoken,我们可以https://jwt.io/ 进行解码查看内容。

ASP.NET Core 6中如何实现JWT认证

2、测试正确用户授权,我们知道我们token中角色是Admin_Test,API 正确返回我们期望结果。其中Headers 里面要增加Authorization 字段。值为:

Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1laWQiOiIxMDAxIiwicm9sZSI6IkFkbWluX1Rlc3QiLCJuYmYiOjE2ODY5ODk4NTQsImV4cCI6MTY4Njk5MTY1NCwiaWF0IjoxNjg2OTg5ODU0LCJpc3MiOiJodHRwOi8vd3d3LnBwZmJoLmNvbSIsImF1ZCI6Imh0dHA6Ly93d3cucHBmYmguY29tIn0.KZJJst8YR9jmhNzN2Qbxd2hXo42tBvWWJVENE2AerSs

ASP.NET Core 6中如何实现JWT认证

3、角色不符合接口测试,返回403 错误。

ASP.NET Core 6中如何实现JWT认证

总结

在 ASP.NET Core 中使用 Authentication 中间件来实现 JWT 身份认证和授权,可以提供安全可靠的身份验证和授权机制,而且实现非常简单,保护用户信息和敏感数据也相对可靠的。但是在实践中,需要遵循安全性和最佳实践,并根据具体情况进行定制化配置和实现,以确保应用程序的安全和可靠性。欢迎大家一起探讨.NET的认证授权,欢迎大家留言与转发。谢谢!

ASP.NET Core 6中如何实现JWT认证