用到的package

    <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.2" />

定义jwt options

public class JWTOptions
{
    public string SigningKey { get; set; }
    public int ExpireSeconds { get; set; }
}

在appsettings.json中加入jwt设置

  "JWT": {
    "SigningKey": "%!magzks4isLCQs4AeK6nJ&h9kf2M^&K",
    "ExpireSeconds": 3600
  }

在program.cs中注入JWT的认证方式

builder.Services.Configure<JWTOptions>(builder.Configuration.GetSection("JWT"));
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        JWTOptions jwtOpt = builder.Configuration.GetSection("JWT").Get<JWTOptions>();
        byte[] keyBytes = Encoding.UTF8.GetBytes(jwtOpt.SigningKey);
        SymmetricSecurityKey secKey = new SymmetricSecurityKey(keyBytes);

        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = false,
            ValidateAudience = false,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            IssuerSigningKey = secKey,
        };
    });

// 调用UseAuthentication
app.UseAuthentication();

加入JWTController

    [ApiController]
    [Route("[controller]")]
    public class JWTController : ControllerBase
    {
        private IOptionsSnapshot<JWTOptions> JwtOptions { get; init; }

        public JWTController(IOptionsSnapshot<JWTOptions> jwtOptions)
        {
            JwtOptions = jwtOptions;
        }

        [HttpPost("login")]
        public ActionResult<string> Login([FromBody] LoginRequest request)
        {
            if (request.Username == "admin" && request.Password == "12345")
            {
                List<Claim> claims = new List<Claim>();

                claims.Add(new Claim(ClaimTypes.NameIdentifier, "1"));
                claims.Add(new Claim(ClaimTypes.Name, request.Username));
                claims.Add(new Claim(ClaimTypes.Role, "admin"));  // 加入Role

                string jwt = BuildJwtToken(claims, JwtOptions.Value);
                Console.WriteLine(jwt);

                return jwt;
            }

            return BadRequest();
        }

        // 生成JWT的token
        private string BuildJwtToken(List<Claim> claims, JWTOptions options)
        {
            string key = options.SigningKey;
            DateTime expiry = DateTime.Now.AddSeconds(options.ExpireSeconds);

            byte[] keyBytes = Encoding.UTF8.GetBytes(key);
            SymmetricSecurityKey secKey = new SymmetricSecurityKey(keyBytes);
            SigningCredentials credentials = new SigningCredentials(secKey, SecurityAlgorithms.HmacSha256Signature);
            JwtSecurityToken token = new JwtSecurityToken(claims: claims, expires: expiry, signingCredentials: credentials);

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

        [HttpGet("hello")]
        [Authorize(Roles = "admin")]   // JWT中必须包含admin的Role
        public ActionResult<string> Hello()
        {
            string id = User.FindFirst(ClaimTypes.NameIdentifier)!.Value;
            string username = User.FindFirst(ClaimTypes.Name)!.Value;

            return Ok($"id={id}, name={username}");
        }
    }

测试

POST https://localhost:7187/JWT/login HTTP/1.1
content-type: application/json

{
    "username": "admin",
    "password": "12345"
}
###

GET https://localhost:7187/JWT/hello HTTP/1.1
content-type: application/json
Authorization: Bearer {{token}}   // 使用上面login返回的token

{
}
###