Add transfer tracking and secure admin access
This commit is contained in:
@@ -15,7 +15,7 @@ var authPermitLimit = Math.Max(1, builder.Configuration.GetValue("RateLimiting:A
|
||||
builder.Services.AddRateLimiter(options =>
|
||||
{
|
||||
options.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
||||
options.AddPolicy("auth", context =>
|
||||
options.AddPolicy("auth", context =>
|
||||
RateLimitPartition.GetFixedWindowLimiter(
|
||||
context.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||||
_ => new FixedWindowRateLimiterOptions
|
||||
@@ -23,7 +23,16 @@ builder.Services.AddRateLimiter(options =>
|
||||
PermitLimit = authPermitLimit,
|
||||
Window = TimeSpan.FromMinutes(1),
|
||||
QueueLimit = 0,
|
||||
}));
|
||||
}));
|
||||
options.AddPolicy("admin-auth", context =>
|
||||
RateLimitPartition.GetFixedWindowLimiter(
|
||||
context.Connection.RemoteIpAddress?.ToString() ?? "unknown",
|
||||
_ => new FixedWindowRateLimiterOptions
|
||||
{
|
||||
PermitLimit = 5,
|
||||
Window = TimeSpan.FromMinutes(1),
|
||||
QueueLimit = 0,
|
||||
}));
|
||||
options.AddPolicy("ai", context =>
|
||||
RateLimitPartition.GetConcurrencyLimiter(
|
||||
context.User.FindFirst("sub")?.Value ??
|
||||
@@ -52,6 +61,8 @@ builder.Services.AddScoped<LedgerResolver>();
|
||||
builder.Services.AddScoped<AiPermissionService>();
|
||||
builder.Services.AddScoped<AiChatQuotaService>();
|
||||
builder.Services.AddScoped<BudgetPushService>();
|
||||
builder.Services.AddScoped<AdminSessionService>();
|
||||
builder.Services.AddScoped<AdminBootstrapService>();
|
||||
builder.Services.AddSingleton<PushTokenProtector>();
|
||||
builder.Services.AddScoped<AiPermissionFilter>();
|
||||
builder.Services.AddHttpClient("LlmClient");
|
||||
@@ -84,9 +95,6 @@ if (string.IsNullOrWhiteSpace(conn))
|
||||
var jwtSecret = builder.Configuration["Jwt:Secret"];
|
||||
if (string.IsNullOrWhiteSpace(jwtSecret) || jwtSecret.Length < 32)
|
||||
throw new InvalidOperationException("必须通过 Jwt__Secret 配置至少 32 位的 JWT 密钥");
|
||||
var adminKey = builder.Configuration["Admin:Key"];
|
||||
if (string.IsNullOrWhiteSpace(adminKey) || adminKey.Length < 24)
|
||||
throw new InvalidOperationException("必须通过 Admin__Key 配置至少 24 位的管理密钥");
|
||||
if (builder.Configuration.GetValue<bool>("Push:Enabled"))
|
||||
{
|
||||
var pushKey = builder.Configuration["Push:TokenEncryptionKey"];
|
||||
@@ -156,7 +164,8 @@ var app = builder.Build();
|
||||
using (var scope = app.Services.CreateScope())
|
||||
{
|
||||
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
|
||||
await db.Database.MigrateAsync();
|
||||
await db.Database.MigrateAsync();
|
||||
await scope.ServiceProvider.GetRequiredService<AdminBootstrapService>().EnsureAsync();
|
||||
if (app.Environment.IsDevelopment())
|
||||
await DbSeeder.SeedAsync(db);
|
||||
}
|
||||
@@ -167,8 +176,9 @@ var buildTime = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") + " UTC";
|
||||
var apiVersion = builder.Configuration["Build:Version"] ?? "dev";
|
||||
|
||||
app.UseAuthentication();
|
||||
app.UseRateLimiter();
|
||||
app.UseAuthorization();
|
||||
app.UseRateLimiter();
|
||||
app.UseAuthorization();
|
||||
app.UseMiddleware<AdminAuditMiddleware>();
|
||||
app.MapControllers();
|
||||
app.MapGet("/api/ping", () => Results.Ok(new { status = "ok", version = apiVersion, built = buildTime }));
|
||||
app.MapGet("/api/version", () => Results.Ok(new { app = "记之 API", version = apiVersion, built = buildTime }));
|
||||
|
||||
Reference in New Issue
Block a user