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

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.xdnf.cn/news/16395.html

相关文章:

  • [2025CVPR-图象分类方向]CATANet:用于轻量级图像超分辨率的高效内容感知标记聚合
  • C# WPF 实现读取文件夹中的PDF并显示其页数
  • 案例分享|告别传统PDA+便携打印机模式,快速实现高效率贴标
  • Class18卷积层的填充和步幅
  • uniapp之微信小程序标题对其右上角按钮胶囊
  • 测试ppyoloe的小样本few-shot能力,10张图片精度达到69.8%
  • Allegro软件光绘文件Artwork到底如何配置?
  • Python柱状图
  • Lakehouse x AI ,打造智能 BI 新体验
  • 戴尔电脑 Linux 安装与配置指南_导入mysql共享文件夹
  • 关于网络模型
  • FreeRTOS—优先级翻转问题
  • vue项目入门
  • 【C++避坑指南】vector迭代器失效的八大场景与解决方案
  • haproxy七层代理(原理)
  • 从0开始学习R语言--Day57--SCAD模型
  • 深入浅出设计模式——创建型模式之简单工厂模式
  • Hive【Hive架构及工作原理】
  • 如何高效通过3GPP官网查找资料
  • JAVA + 海康威视SDK + FFmpeg+ SRS 实现海康威视摄像头二次开发
  • 服务器托管:网站经常被攻击该怎么办?
  • 学习游戏制作记录(克隆技能)7.25
  • 秋招Day19 - 分布式 - 分布式锁
  • 初识决策树-理论部分
  • 肺癌预测模型实战案例
  • 【自动化运维神器Ansible】Ansible常用模块之Copy模块详解
  • 文件包含学习总结
  • 滑动窗口-7
  • 主要分布在背侧海马体(dHPC)CA1区域(dCA1)的时空联合细胞对NLP中的深层语义分析的积极影响和启示
  • ClickHouse 常用的使用场景