我正在开发一个 .NET 8 项目,需要在运行时动态修改(更新、删除、添加)JWT 架构。我在 ASP.NET Core 中使用内置的 JWT 身份验证。我的模式和受众可能会改变,我想改变这一点而不回收。我当前的代码:
应用程序设置
{
"AuthRules": [
{
"Service": "scheme1",
"Audiences": [ "aud1", "aud2" ]
},
{
"Service": "Scheme2",
"Audiences": [ "aud1", "aud2", "aud3" ]
}
}
添加JWT方法
public static void AddAuthRules(WebApplicationBuilder builder)
{
var signingKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("test"));
foreach (var rule in AppConfig.getValues("AuthRules"))
{
List<string> audiences = new List<string>();
foreach (KeyValuePair<string, string?> item in rule.GetSection("Audiences").AsEnumerable())
{
if (!string.IsNullOrEmpty(item.Value))
audiences.Add(item.Value);
}
var tokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = signingKey,
ValidateIssuer = true,
ValidIssuer = "issExample",
ValidateAudience = true,
ValidAudiences = audiences,
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = false
};
builder.Services.AddAuthentication()
.AddJwtBearer(rule.GetSection("Service").Value!, x =>
{
x.Events = new JwtBearerEvents
{
OnTokenValidated = context =>
{
// Add custom logic for token validation success
return Task.CompletedTask;
},
OnAuthenticationFailed = context =>
{
// Add custom logic for authentication failure
return Task.CompletedTask;
}
};
x.RequireHttpsMetadata = false;
x.TokenValidationParameters = tokenValidationParameters;
});
}
}
public static class JwtAuthConfiguration
{
// In-memory cache to hold JWT authentication configurations
private static readonly ConcurrentDictionary<string, TokenValidationParameters> _authConfigurations = new();
public static void AddAuthRules(WebApplicationBuilder builder)
{
// Your existing code to read configurations from appsettings.json
foreach (var rule in AppConfig.getValues("AuthRules"))
{
List<string> audiences = new List<string>();
// Your existing code to parse audiences from configuration
var tokenValidationParameters = new TokenValidationParameters
{
// Your existing token validation parameters
};
// Add the token validation parameters to the in-memory cache
_authConfigurations.TryAdd(rule.GetSection("Service").Value!, tokenValidationParameters);
// Add JWT authentication handler
AddJwtAuthentication(builder, rule.GetSection("Service").Value!, tokenValidationParameters);
}
}
private static void AddJwtAuthentication(WebApplicationBuilder builder, string serviceName, TokenValidationParameters validationParameters)
{
builder.Services.AddAuthentication()
.AddJwtBearer(serviceName, x =>
{
// Your existing JWT bearer configuration
x.TokenValidationParameters = validationParameters;
});
}
// Method to update JWT authentication configurations at runtime
public static void UpdateAuthConfiguration(string serviceName, TokenValidationParameters newValidationParameters)
{
// Update the configuration in the in-memory cache
_authConfigurations.AddOrUpdate(serviceName, newValidationParameters, (key, oldValue) => newValidationParameters);
// Retrieve the current application builder
var builder = /* Obtain the current WebApplicationBuilder */;
// Remove the existing JWT authentication handler
builder.Services.RemoveAuthentication(serviceName);
// Add the updated JWT authentication handler
AddJwtAuthentication(builder, serviceName, newValidationParameters);
}
}