From bfdfad14d845514231815ef54ca031c6fb00d0c4 Mon Sep 17 00:00:00 2001
From: glz <694770232@qq.com>
Date: Thu, 2 Jul 2026 08:52:41 +0800
Subject: [PATCH] =?UTF-8?q?refactor(auth):=20=E9=87=8D=E6=9E=84JWT?=
=?UTF-8?q?=E8=AE=A4=E8=AF=81=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81=EF=BC=8C?=
=?UTF-8?q?=E4=BC=98=E5=8C=96=E5=A3=B0=E6=98=8E=E8=8E=B7=E5=8F=96=E9=80=BB?=
=?UTF-8?q?=E8=BE=91?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
1. 提取通用的GetClaim方法简化多声明类型查找逻辑
2. 重构JWT认证配置代码,拆分配置逻辑到单独方法
3. 优化开发环境下的认证策略,支持无认证和JWT认证自动切换
---
.../Auth/JwtHelper.cs | 9 +-
.../DependencyInjectionExtensions.cs | 127 +++++++++++-------
2 files changed, 82 insertions(+), 54 deletions(-)
diff --git a/QYZH.InteractiveMagazine.Infrastructure/Auth/JwtHelper.cs b/QYZH.InteractiveMagazine.Infrastructure/Auth/JwtHelper.cs
index f1f7310..9cc7b28 100644
--- a/QYZH.InteractiveMagazine.Infrastructure/Auth/JwtHelper.cs
+++ b/QYZH.InteractiveMagazine.Infrastructure/Auth/JwtHelper.cs
@@ -119,7 +119,7 @@ public static class JwtHelper
var tokenHandler = new JwtSecurityTokenHandler();
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
{
- var userIdClaim = jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier);
+ var userIdClaim = GetClaim(jwtToken, ClaimTypes.NameIdentifier, JwtRegisteredClaimNames.NameId, JwtRegisteredClaimNames.Sub);
if (long.TryParse(userIdClaim?.Value, out long userId))
{
return userId;
@@ -157,8 +157,13 @@ public static class JwtHelper
var tokenHandler = new JwtSecurityTokenHandler();
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
{
- return jwtToken.Claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value ?? string.Empty;
+ return GetClaim(jwtToken, ClaimTypes.Name, JwtRegisteredClaimNames.UniqueName, JwtRegisteredClaimNames.Name)?.Value ?? string.Empty;
}
return string.Empty;
}
+
+ private static Claim? GetClaim(JwtSecurityToken jwtToken, params string[] claimTypes)
+ {
+ return jwtToken.Claims.FirstOrDefault(c => claimTypes.Contains(c.Type));
+ }
}
diff --git a/QYZH.InteractiveMagazine.Infrastructure/Extensions/DependencyInjectionExtensions.cs b/QYZH.InteractiveMagazine.Infrastructure/Extensions/DependencyInjectionExtensions.cs
index ebfc4e7..c0e8c3b 100644
--- a/QYZH.InteractiveMagazine.Infrastructure/Extensions/DependencyInjectionExtensions.cs
+++ b/QYZH.InteractiveMagazine.Infrastructure/Extensions/DependencyInjectionExtensions.cs
@@ -21,6 +21,9 @@ namespace QYZH.InteractiveMagazine.Infrastructure.Extensions;
///
public static class DependencyInjectionExtensions
{
+ private const string NoAuthScheme = "NoAuth";
+ private const string DevelopmentAuthScheme = "DevelopmentSmartAuth";
+
///
/// Registers infrastructure services.
///
@@ -34,70 +37,90 @@ public static class DependencyInjectionExtensions
private static void AddJwtAuthentication(IServiceCollection services, IConfiguration configuration, IWebHostEnvironment? environment = null)
{
+ var jwtSettings = configuration.GetSection("JwtSettings").Get()!;
+ services.AddSingleton(jwtSettings);
+
if (environment?.IsDevelopment() == true)
{
- services.AddAuthentication("NoAuth")
- .AddScheme("NoAuth", options => { });
+ services.AddAuthentication(options =>
+ {
+ options.DefaultScheme = DevelopmentAuthScheme;
+ options.DefaultChallengeScheme = DevelopmentAuthScheme;
+ })
+ .AddPolicyScheme(DevelopmentAuthScheme, null, options =>
+ {
+ options.ForwardDefaultSelector = context =>
+ {
+ var authHeader = context.Request.Headers.Authorization.FirstOrDefault();
+ return !string.IsNullOrWhiteSpace(authHeader) &&
+ authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase)
+ ? JwtBearerDefaults.AuthenticationScheme
+ : NoAuthScheme;
+ };
+ })
+ .AddJwtBearer(JwtBearerDefaults.AuthenticationScheme, options => ConfigureJwtBearer(options, jwtSettings))
+ .AddScheme(NoAuthScheme, options => { });
return;
}
- var jwtSettings = configuration.GetSection("JwtSettings").Get()!;
-
- services.AddSingleton(jwtSettings);
-
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
- .AddJwtBearer(options =>
+ .AddJwtBearer(options => ConfigureJwtBearer(options, jwtSettings));
+ }
+
+ private static void ConfigureJwtBearer(JwtBearerOptions options, JwtSettings jwtSettings)
+ {
+ options.TokenValidationParameters = new TokenValidationParameters
+ {
+ ValidateIssuer = true,
+ ValidIssuer = jwtSettings.Issuer,
+ ValidateAudience = true,
+ ValidAudience = jwtSettings.Audience,
+ ValidateIssuerSigningKey = true,
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey!)),
+ ValidateLifetime = true,
+ ClockSkew = TimeSpan.Zero
+ };
+
+ options.Events = new JwtBearerEvents
+ {
+ OnTokenValidated = async context =>
{
- options.TokenValidationParameters = new TokenValidationParameters
+ var currentToken = GetBearerToken(context);
+ if (string.IsNullOrEmpty(currentToken))
{
- ValidateIssuer = true,
- ValidIssuer = jwtSettings.Issuer,
- ValidateAudience = true,
- ValidAudience = jwtSettings.Audience,
- ValidateIssuerSigningKey = true,
- IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(jwtSettings.SecretKey!)),
- ValidateLifetime = true,
- ClockSkew = TimeSpan.Zero
- };
+ context.Fail("Invalid token");
+ return;
+ }
- options.Events = new JwtBearerEvents
+ var userId = context.Principal?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
+ if (string.IsNullOrEmpty(userId))
{
- OnTokenValidated = async context =>
+ context.Fail("Invalid token");
+ return;
+ }
+
+ var wxUserId = context.Principal?.FindFirst(JwtHelper.WxUserIdClaimType)?.Value;
+ if (string.IsNullOrEmpty(wxUserId))
+ {
+ var adminToken = await RedisHelper.GetAsync(JwtHelper.BuildAdminTokenKey(userId));
+ if (adminToken == currentToken)
{
- var currentToken = GetBearerToken(context);
- if (string.IsNullOrEmpty(currentToken))
- {
- context.Fail("Invalid token");
- return;
- }
-
- var userId = context.Principal?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
- if (string.IsNullOrEmpty(userId))
- {
- context.Fail("Invalid token");
- return;
- }
-
- var adminToken = await RedisHelper.GetAsync(JwtHelper.BuildAdminTokenKey(userId));
- var wxUserId = context.Principal?.FindFirst(JwtHelper.WxUserIdClaimType)?.Value;
- if (string.IsNullOrEmpty(wxUserId) && !string.IsNullOrEmpty(adminToken))
- {
- return;
- }
-
- if (!string.IsNullOrEmpty(wxUserId))
- {
- var wechatToken = await RedisHelper.GetAsync(JwtHelper.BuildWeChatTokenKey(wxUserId, userId));
- if (wechatToken == currentToken)
- {
- return;
- }
- }
-
- context.Fail("Token expired, please login again");
+ return;
}
- };
- });
+
+ context.Fail("Token expired, please login again");
+ return;
+ }
+
+ var wechatToken = await RedisHelper.GetAsync(JwtHelper.BuildWeChatTokenKey(wxUserId, userId));
+ if (wechatToken == currentToken)
+ {
+ return;
+ }
+
+ context.Fail("Token expired, please login again");
+ }
+ };
}
private static string? GetBearerToken(TokenValidatedContext context)