refactor(auth): 重构JWT认证相关代码,优化声明获取逻辑
1. 提取通用的GetClaim方法简化多声明类型查找逻辑 2. 重构JWT认证配置代码,拆分配置逻辑到单独方法 3. 优化开发环境下的认证策略,支持无认证和JWT认证自动切换
This commit is contained in:
@ -119,7 +119,7 @@ public static class JwtHelper
|
|||||||
var tokenHandler = new JwtSecurityTokenHandler();
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
|
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))
|
if (long.TryParse(userIdClaim?.Value, out long userId))
|
||||||
{
|
{
|
||||||
return userId;
|
return userId;
|
||||||
@ -157,8 +157,13 @@ public static class JwtHelper
|
|||||||
var tokenHandler = new JwtSecurityTokenHandler();
|
var tokenHandler = new JwtSecurityTokenHandler();
|
||||||
if (tokenHandler.ReadToken(token) is JwtSecurityToken jwtToken)
|
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;
|
return string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Claim? GetClaim(JwtSecurityToken jwtToken, params string[] claimTypes)
|
||||||
|
{
|
||||||
|
return jwtToken.Claims.FirstOrDefault(c => claimTypes.Contains(c.Type));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,6 +21,9 @@ namespace QYZH.InteractiveMagazine.Infrastructure.Extensions;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class DependencyInjectionExtensions
|
public static class DependencyInjectionExtensions
|
||||||
{
|
{
|
||||||
|
private const string NoAuthScheme = "NoAuth";
|
||||||
|
private const string DevelopmentAuthScheme = "DevelopmentSmartAuth";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Registers infrastructure services.
|
/// Registers infrastructure services.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -34,19 +37,37 @@ public static class DependencyInjectionExtensions
|
|||||||
|
|
||||||
private static void AddJwtAuthentication(IServiceCollection services, IConfiguration configuration, IWebHostEnvironment? environment = null)
|
private static void AddJwtAuthentication(IServiceCollection services, IConfiguration configuration, IWebHostEnvironment? environment = null)
|
||||||
{
|
{
|
||||||
|
var jwtSettings = configuration.GetSection("JwtSettings").Get<JwtSettings>()!;
|
||||||
|
services.AddSingleton(jwtSettings);
|
||||||
|
|
||||||
if (environment?.IsDevelopment() == true)
|
if (environment?.IsDevelopment() == true)
|
||||||
{
|
{
|
||||||
services.AddAuthentication("NoAuth")
|
services.AddAuthentication(options =>
|
||||||
.AddScheme<AuthenticationSchemeOptions, NoAuthHandler>("NoAuth", 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<AuthenticationSchemeOptions, NoAuthHandler>(NoAuthScheme, options => { });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jwtSettings = configuration.GetSection("JwtSettings").Get<JwtSettings>()!;
|
|
||||||
|
|
||||||
services.AddSingleton(jwtSettings);
|
|
||||||
|
|
||||||
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
|
||||||
.AddJwtBearer(options =>
|
.AddJwtBearer(options => ConfigureJwtBearer(options, jwtSettings));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ConfigureJwtBearer(JwtBearerOptions options, JwtSettings jwtSettings)
|
||||||
{
|
{
|
||||||
options.TokenValidationParameters = new TokenValidationParameters
|
options.TokenValidationParameters = new TokenValidationParameters
|
||||||
{
|
{
|
||||||
@ -78,26 +99,28 @@ public static class DependencyInjectionExtensions
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var adminToken = await RedisHelper.GetAsync(JwtHelper.BuildAdminTokenKey(userId));
|
|
||||||
var wxUserId = context.Principal?.FindFirst(JwtHelper.WxUserIdClaimType)?.Value;
|
var wxUserId = context.Principal?.FindFirst(JwtHelper.WxUserIdClaimType)?.Value;
|
||||||
if (string.IsNullOrEmpty(wxUserId) && !string.IsNullOrEmpty(adminToken))
|
if (string.IsNullOrEmpty(wxUserId))
|
||||||
|
{
|
||||||
|
var adminToken = await RedisHelper.GetAsync(JwtHelper.BuildAdminTokenKey(userId));
|
||||||
|
if (adminToken == currentToken)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(wxUserId))
|
context.Fail("Token expired, please login again");
|
||||||
{
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var wechatToken = await RedisHelper.GetAsync(JwtHelper.BuildWeChatTokenKey(wxUserId, userId));
|
var wechatToken = await RedisHelper.GetAsync(JwtHelper.BuildWeChatTokenKey(wxUserId, userId));
|
||||||
if (wechatToken == currentToken)
|
if (wechatToken == currentToken)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
context.Fail("Token expired, please login again");
|
context.Fail("Token expired, please login again");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string? GetBearerToken(TokenValidatedContext context)
|
private static string? GetBearerToken(TokenValidatedContext context)
|
||||||
|
|||||||
Reference in New Issue
Block a user