ASP.NET Core 中间件:解析 JWT 并注入用户上下文的最佳实践
在ASP.NET Core 中,可以通过自定义中间件解析 JWT 并将用户信息提取到HttpContext
的用户上下文中(如HttpContext.User
),以便在后续的处理中使用这些信息(如授权、日志记录等)。以下是实现步骤和完整示例:
1. 背景
JWT(JSON Web Token)是一种广泛使用的身份验证机制。一般情况下,JWT 会包含在 HTTP 请求的Authorization
头部中,格式如下:
Authorization: Bearer <token>
我们需要在中间件中:
- 从请求头中提取 JWT。
- 验证 JWT 的合法性(如签名、过期时间)。
- 将解析出的用户信息(如
Claims
)注入到HttpContext.User
。
2. 实现步骤
步骤 1:添加依赖包
使用Microsoft.AspNetCore.Authentication.JwtBearer
处理 JWT 验证。
dotnet add package Microsoft.AspNetCore.Authentication.JwtBearer
步骤 2:配置 JWT 参数
在appsettings.json
或代码中配置 JWT 的密钥、颁发者和受众等信息。
appsettings.json
示例:
{
"JwtSettings": {
"Issuer": "your-issuer",
"Audience": "your-audience",
"SecretKey": "your-secret-key"
}
}
步骤 3:创建 JWT 中间件
以下是一个自定义中间件的实现:
using Microsoft.AspNetCore.Http;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
publicclassJwtMiddleware
{
privatereadonly RequestDelegate _next;
privatereadonlystring _secretKey;
privatereadonlystring _issuer;
privatereadonlystring _audience;
public JwtMiddleware(RequestDelegate next, IConfiguration configuration)
{
_next = next;
var jwtSettings = configuration.GetSection("JwtSettings");
_secretKey = jwtSettings["SecretKey"];
_issuer = jwtSettings["Issuer"];
_audience = jwtSettings["Audience"];
}
public async Task InvokeAsync(HttpContext context)
{
var token = context.Request.Headers["Authorization"].FirstOrDefault()?.Split(" ").Last();
if (!string.IsNullOrEmpty(token))
{
AttachUserToContext(context, token);
}
// 调用下一个中间件
await _next(context);
}
private void AttachUserToContext(HttpContext context, string token)
{
try
{
var tokenHandler = new JwtSecurityTokenHandler();
var key = Encoding.UTF8.GetBytes(_secretKey);
// 验证令牌
var validationParameters = new TokenValidationParameters
{
ValidateIssuer = true,
ValidateAudience = true,
ValidateLifetime = true,
ValidateIssuerSigningKey = true,
ValidIssuer = _issuer,
ValidAudience = _audience,
IssuerSigningKey = new SymmetricSecurityKey(key)
};
var principal = tokenHandler.ValidateToken(token, validationParameters, out SecurityToken validatedToken);
// 将用户信息注入 HttpContext.User
context.User = principal;
}
catch (Exception ex)
{
// 如果令牌无效,忽略错误并不设置 HttpContext.User
Console.WriteLine($"JWT validation failed: {ex.Message}");
}
}
}
步骤 4:注册中间件
在Startup.cs
或Program.cs
中注册自定义中间件。
public classStartup
{
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseMiddleware<JwtMiddleware>();
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
3. 测试流程
请求头中带有有效的 JWT
假设 JWT 的Claims
中包含以下信息:
{
"sub": "1234567890",
"name": "John Doe",
"role": "Admin"
}
通过JwtMiddleware
验证后,HttpContext.User
会包含这些 Claims,可以在控制器或其他中间件中通过以下方式访问:
[HttpGet("test")]
public IActionResult Test()
{
var userId = User.FindFirstValue(ClaimTypes.NameIdentifier); // 1234567890
var userName = User.Identity.Name; // John Doe
var userRole = User.FindFirstValue(ClaimTypes.Role); // Admin
return Ok(new { userId, userName, userRole });
}
请求头中没有 JWT 或 JWT 无效
- 如果请求头中不包含 JWT,中间件将跳过用户上下文的设置,
HttpContext.User
为匿名用户。 - 如果 JWT 无效(如签名错误、过期等),中间件会捕获异常,并保持
HttpContext.User
为匿名用户。
4. JWT 中间件的应用场景
-
验证用户身份:
- 在每个请求中解析 JWT,以确定请求是否来自合法用户。
-
提取用户信息:
- 将用户信息注入
HttpContext.User
,供后续的中间件、控制器或服务访问。 -
统一用户上下文:
- 所有基于身份的功能(如角色授权、权限验证)都依赖于
HttpContext.User
。 -
轻量级认证:
- 在无状态的 RESTful API 中,通过 JWT 中间件实现无会话的认证和上下文管理。
总结
通过自定义中间件解析 JWT,可以高效、灵活地处理用户上下文信息,将其注入到HttpContext.User
中,方便后续的业务逻辑开发。这种方式适用于 RESTful API、微服务架构等无状态的场景,增强了系统的安全性和可扩展性。
作者:阿笨
【官方QQ一群:跟着阿笨一起玩NET(已满)】:422315558
【官方QQ二群:跟着阿笨一起玩C#(已满)】:574187616
【官方QQ三群:跟着阿笨一起玩ASP.NET(已满)】:967920586
【官方QQ四群:Asp.Net Core跨平台技术开发(可加入)】:829227829
【官方QQ五群:.NET Core跨平台开发技术(可加入)】:647639415
【网易云课堂】:https://study.163.com/provider/2544628/index.htm?share=2&shareId=2544628
【51CTO学院】:https://edu.51cto.com/sd/66c64
【微信公众号】:微信搜索:跟着阿笨一起玩NET
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2021-02-04 SQL Server数据库高级进阶之事务实战演练
2021-02-04 C#如何正确运用异步编程技术
2021-02-04 SQL Server数据库高级进阶之锁实战演练
2020-02-04 .NET Core基于SQL Server数据库主从同步实现读写分离实战演练
2013-02-04 将要被社会淘汰的8种人