当前位置: 首页 > news >正文

jwt 在net9.0中做身份认证

一、新建net9.0项目WebApplication1,安装包

  <ItemGroup><PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.7" /><PackageReference Include="Swashbuckle.AspNetCore" Version="9.0.3" /></ItemGroup>

在线生成TOKEN:JWT在线解码/编码工具 - 解析、验证、生成JSON Web Token 

Program.cs

using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Models;
using System.Text;
using System.Text.Json;var builder = WebApplication.CreateBuilder(args);// 配置 JWT 认证
var secretKey = "Tx7S/FjYAnh3LDpyOcysrZ0K6e2cWlIX4p8/X8xV2U0vqY4kbZ4EZFI8s0qc35T5Z80RbTkc0F/JE6UnQzwIcw==";
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{ // 显示详细的 PII 错误(仅限开发环境!)options.IncludeErrorDetails = true;  // 👈 返回错误详情options.TokenValidationParameters = new TokenValidationParameters{ValidateIssuerSigningKey = true,IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(secretKey)),ValidateIssuer = false,ValidateAudience = false,ValidateLifetime = true,ClockSkew = TimeSpan.Zero};// 捕获 JWT 验证事件options.Events = new JwtBearerEvents{OnAuthenticationFailed = context =>{// 捕获验证失败的原因Console.WriteLine($"JWT 验证失败: {context.Exception.Message}");// 可以在这里返回自定义错误信息(但生产环境不建议返回详细错误)context.Response.StatusCode = 401;context.Response.ContentType = "application/json";var errorMessage = new{error = "Unauthorized",message = context.Exception.Message // 返回具体错误信息};return context.Response.WriteAsync(JsonSerializer.Serialize(errorMessage));},OnChallenge = context =>{// 当请求未提供 token 时触发Console.WriteLine("请求未提供 JWT Token");return Task.CompletedTask;},OnTokenValidated = context =>{// Token 验证成功时触发Console.WriteLine("JWT 验证成功");return Task.CompletedTask;}};});// 配置 Swagger
builder.Services.AddSwaggerGen(c =>
{c.SwaggerDoc("v1", new OpenApiInfo { Title = "JWT Auth API", Version = "v1" });// 添加 JWT 认证支持到 Swaggerc.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme{Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",Name = "Authorization",In = ParameterLocation.Header,Type = SecuritySchemeType.ApiKey,Scheme = "Bearer"});c.AddSecurityRequirement(new OpenApiSecurityRequirement{{new OpenApiSecurityScheme{Reference = new OpenApiReference{Type = ReferenceType.SecurityScheme,Id = "Bearer"}},Array.Empty<string>()}});
}); builder.Services.AddCors(options =>
{options.AddPolicy("AllowAll", policy =>{policy.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); // 必须允许 Authorization 头});
});// 添加服务到容器
builder.Services.AddControllers();var app = builder.Build();// 配置 HTTP 请求管道
if (app.Environment.IsDevelopment())
{app.UseSwagger();app.UseSwaggerUI(c =>{c.SwaggerEndpoint("/swagger/v1/swagger.json", "JWT Auth API v1");});
}app.UseCors("AllowAll");app.UseAuthentication(); // 必须在 UseAuthorization 之前
app.UseAuthorization();app.MapControllers();app.Run();

获取token:

AuthController

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;namespace JwtAuthApi.Controllers;[ApiController]
[Route("api/[controller]")]
public class AuthController : ControllerBase
{private readonly IConfiguration _configuration;public AuthController(IConfiguration configuration){_configuration = configuration;}[HttpPost("login")][AllowAnonymous]public IActionResult Login([FromBody] LoginModel login){// 这里应该有实际的用户验证逻辑// 这里只是示例,直接接受任何用户名/密码if (string.IsNullOrEmpty(login.Username)){return BadRequest("Username is required");}// 创建 tokenvar tokenHandler = new JwtSecurityTokenHandler();var key = Encoding.UTF8.GetBytes("Tx7S/FjYAnh3LDpyOcysrZ0K6e2cWlIX4p8/X8xV2U0vqY4kbZ4EZFI8s0qc35T5Z80RbTkc0F/JE6UnQzwIcw==");var tokenDescriptor = new SecurityTokenDescriptor{Subject = new ClaimsIdentity(new[]{new Claim(ClaimTypes.NameIdentifier, Guid.NewGuid().ToString()),new Claim(ClaimTypes.Name, login.Username)}),Expires = DateTime.UtcNow.AddHours(1),SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)};var token = tokenHandler.CreateToken(tokenDescriptor);var tokenString = tokenHandler.WriteToken(token);return Ok(new{Token = tokenString,ExpiresIn = (int)TimeSpan.FromHours(1).TotalSeconds});}
}public class LoginModel
{public string Username { get; set; }public string Password { get; set; }
}

WeatherForecastController.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;namespace JwtAuthApi.Controllers;[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{private static readonly string[] Summaries = new[]{"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"};[HttpGet][Authorize] // 需要认证public IEnumerable<WeatherForecast> Get(){// 可以从 User 中获取 JWT 中的声明var userName = User.Identity?.Name;var userId = User.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;Console.WriteLine($"User {userName} (ID: {userId}) accessed weather forecast");return Enumerable.Range(1, 5).Select(index => new WeatherForecast{Date = DateTime.Now.AddDays(index),TemperatureC = Random.Shared.Next(-20, 55),Summary = Summaries[Random.Shared.Next(Summaries.Length)]}).ToArray();}
}public class WeatherForecast
{public DateTime Date { get; set; }public int TemperatureC { get; set; }public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);public string? Summary { get; set; }
}

http://www.lryc.cn/news/600117.html

相关文章:

  • qt框架,使用webEngine如何调试前端
  • 开发笔记 | 优化对话管理器脚本与对话语音的实现
  • 13.使用C连接mysql
  • Jenkins中出现pytest: error: unrecognized arguments: --alluredir=report错误解决办法
  • 栈----1.有效的括号
  • 机器学习 KNN 算法,鸢尾花案例
  • 从Taro的Dialog.open出发,学习远程控制组件之【事件驱动】
  • C++ 多线程同步机制详解:互斥锁、条件变量与原子操作
  • Python Multiprocessing 进程池完全教程:从理论到实战
  • 数据结构(3)单链表
  • [尚庭公寓]14-找房模块
  • Canal 1.1.7的安装
  • 习题5.6 “数学黑洞“
  • PHP插件开发中的一个错误:JSON直接输出导致网站首页异常
  • 纸板留声机:用ESP32和NFC打造会唱歌的复古装置
  • 手语式映射:Kinova Gen3 力控机械臂自适应控制的研究与应用
  • 秒收蜘蛛池解析机制的原理
  • PPIO上线阿里旗舰推理模型Qwen3-235B-A22B-Thinking-2507
  • ATR2652SGNSS全频段低噪声放大器
  • PostgreSQL对象权限管理
  • GPU 驱动安装升级测试
  • [NPUCTF2020]ReadlezPHP
  • CSS 盒子模型学习版的理解
  • C语言第 9 天学习笔记:数组(二维数组与字符数组)
  • ODFM(正交频分复用)系统中加入汉明码(Hamming Code)的主要目的是增强抗误码能力,通过**前向纠错(FEC)**机制提高传输可靠性
  • KNN算法:从原理到实战全解析
  • Kubernetes深度解析:企业级容器编排平台的核心实践
  • 内存 管理
  • LeetCode 233:数字 1 的个数
  • ACL:访问控制列表