@@ -1,20 +1,25 @@
|
||||
using Asp.Versioning;
|
||||
using Asp.Versioning.ApiExplorer;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using TakeoutSaaS.Shared.Abstractions.Security;
|
||||
using TakeoutSaaS.Shared.Abstractions.Serialization;
|
||||
using TakeoutSaaS.Shared.Web.Filters;
|
||||
using Microsoft.AspNetCore.Cors.Infrastructure;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using OpenTelemetry.Metrics;
|
||||
using OpenTelemetry.Resources;
|
||||
using OpenTelemetry.Trace;
|
||||
using Serilog;
|
||||
using TakeoutSaaS.Application.App.Extensions;
|
||||
using TakeoutSaaS.Application.Dictionary.Extensions;
|
||||
using TakeoutSaaS.Application.Identity.Extensions;
|
||||
using TakeoutSaaS.Application.Messaging.Extensions;
|
||||
using TakeoutSaaS.Infrastructure.App.Extensions;
|
||||
using TakeoutSaaS.Infrastructure.Dictionary.Extensions;
|
||||
using TakeoutSaaS.Infrastructure.Identity.Extensions;
|
||||
using TakeoutSaaS.Module.Authorization.Extensions;
|
||||
using TakeoutSaaS.Module.Messaging.Extensions;
|
||||
using TakeoutSaaS.Module.Tenancy.Extensions;
|
||||
using TakeoutSaaS.Shared.Abstractions.Security;
|
||||
using TakeoutSaaS.Shared.Abstractions.Serialization;
|
||||
using TakeoutSaaS.Shared.Web.Extensions;
|
||||
using TakeoutSaaS.Shared.Web.Filters;
|
||||
using TakeoutSaaS.Shared.Web.Security;
|
||||
using TakeoutSaaS.Shared.Web.Swagger;
|
||||
|
||||
@@ -81,15 +86,29 @@ if (isDevelopment)
|
||||
}
|
||||
|
||||
// 5. 注册鉴权授权与权限策略
|
||||
builder.Services.AddAppApplication();
|
||||
builder.Services.AddAppInfrastructure(builder.Configuration);
|
||||
builder.Services.AddJwtAuthentication(builder.Configuration);
|
||||
builder.Services.AddTenantResolution(builder.Configuration);
|
||||
builder.Services.AddAuthorization();
|
||||
builder.Services.AddPermissionAuthorization();
|
||||
builder.Services.AddHealthChecks();
|
||||
|
||||
// 6. 配置 OpenTelemetry 采集
|
||||
// 6. 注册应用层与基础设施(仅租户侧所需)
|
||||
builder.Services.AddAppApplication();
|
||||
builder.Services.AddIdentityApplication(enableMiniSupport: false);
|
||||
builder.Services.AddAppInfrastructure(builder.Configuration);
|
||||
builder.Services.AddIdentityInfrastructure(builder.Configuration, enableMiniFeatures: false, enableAdminSeed: false);
|
||||
|
||||
// 7. 注册多租户解析(依赖 ITenantRepository,需在 Infrastructure 之后)
|
||||
builder.Services.AddTenantResolution(builder.Configuration);
|
||||
|
||||
// 8. 注册字典模块(系统参数、字典项、缓存等)
|
||||
builder.Services.AddDictionaryApplication();
|
||||
builder.Services.AddDictionaryInfrastructure(builder.Configuration);
|
||||
|
||||
// 9. 注册消息发布能力(未配置 RabbitMQ 时自动降级为 NoOp 实现)
|
||||
builder.Services.AddMessagingApplication();
|
||||
builder.Services.AddMessagingModule(builder.Configuration);
|
||||
|
||||
// 10. 配置 OpenTelemetry 采集
|
||||
var otelSection = builder.Configuration.GetSection("Otel");
|
||||
var otelEndpoint = otelSection.GetValue<string>("Endpoint");
|
||||
var useConsoleExporter = otelSection.GetValue<bool?>("UseConsoleExporter") ?? builder.Environment.IsDevelopment();
|
||||
@@ -105,7 +124,6 @@ builder.Services.AddOpenTelemetry()
|
||||
.AddAspNetCoreInstrumentation()
|
||||
.AddHttpClientInstrumentation()
|
||||
.AddEntityFrameworkCoreInstrumentation();
|
||||
// 1. (空行后) 配置 OTLP 导出
|
||||
if (!string.IsNullOrWhiteSpace(otelEndpoint))
|
||||
{
|
||||
tracing.AddOtlpExporter(exporter =>
|
||||
@@ -113,7 +131,6 @@ builder.Services.AddOpenTelemetry()
|
||||
exporter.Endpoint = new Uri(otelEndpoint);
|
||||
});
|
||||
}
|
||||
// 2. (空行后) 配置 Console 导出
|
||||
if (useConsoleExporter)
|
||||
{
|
||||
tracing.AddConsoleExporter();
|
||||
@@ -126,7 +143,6 @@ builder.Services.AddOpenTelemetry()
|
||||
.AddHttpClientInstrumentation()
|
||||
.AddRuntimeInstrumentation()
|
||||
.AddPrometheusExporter();
|
||||
// 1. (空行后) 配置 OTLP 导出
|
||||
if (!string.IsNullOrWhiteSpace(otelEndpoint))
|
||||
{
|
||||
metrics.AddOtlpExporter(exporter =>
|
||||
@@ -134,14 +150,13 @@ builder.Services.AddOpenTelemetry()
|
||||
exporter.Endpoint = new Uri(otelEndpoint);
|
||||
});
|
||||
}
|
||||
// 2. (空行后) 配置 Console 导出
|
||||
if (useConsoleExporter)
|
||||
{
|
||||
metrics.AddConsoleExporter();
|
||||
}
|
||||
});
|
||||
|
||||
// 7. 配置 CORS
|
||||
// 11. 配置 CORS
|
||||
var tenantOrigins = ResolveCorsOrigins(builder.Configuration, "Cors:Tenant");
|
||||
builder.Services.AddCors(options =>
|
||||
{
|
||||
@@ -151,21 +166,23 @@ builder.Services.AddCors(options =>
|
||||
});
|
||||
});
|
||||
|
||||
// 8. 构建应用并配置中间件管道
|
||||
// 12. 构建应用并配置中间件管道
|
||||
var app = builder.Build();
|
||||
app.UseCors("TenantApiCors");
|
||||
|
||||
// 1. (空行后) 通用 Web Core 中间件(异常、ProblemDetails、日志等)
|
||||
app.UseSharedWebCore();
|
||||
|
||||
// 2. (空行后) 执行认证并解析租户
|
||||
// 1. (空行后) 先完成身份认证,确保租户解析优先使用 Token Claim
|
||||
app.UseAuthentication();
|
||||
|
||||
// 2. (空行后) 解析并注入租户上下文(已认证请求不允许 Header 覆盖)
|
||||
app.UseTenantResolution();
|
||||
|
||||
// 3. (空行后) 执行授权
|
||||
// 3. (空行后) 通用 Web Core 中间件(异常、ProblemDetails、日志等)
|
||||
app.UseSharedWebCore();
|
||||
|
||||
// 4. (空行后) 执行授权
|
||||
app.UseAuthorization();
|
||||
|
||||
// 4. (空行后) 开发环境启用 Swagger
|
||||
// 5. (空行后) 开发环境启用 Swagger
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseSharedSwagger();
|
||||
@@ -175,7 +192,7 @@ app.MapPrometheusScrapingEndpoint();
|
||||
app.MapControllers();
|
||||
app.Run();
|
||||
|
||||
// 10. 解析配置中的 CORS 域名
|
||||
// 13. 解析配置中的 CORS 域名
|
||||
static string[] ResolveCorsOrigins(IConfiguration configuration, string sectionKey)
|
||||
{
|
||||
var origins = configuration.GetSection(sectionKey).Get<string[]>();
|
||||
@@ -185,7 +202,7 @@ static string[] ResolveCorsOrigins(IConfiguration configuration, string sectionK
|
||||
.ToArray() ?? [];
|
||||
}
|
||||
|
||||
// 10. 构建 CORS 策略
|
||||
// 14. 构建 CORS 策略
|
||||
static void ConfigureCorsPolicy(CorsPolicyBuilder policy, string[] origins)
|
||||
{
|
||||
if (origins.Length == 0)
|
||||
@@ -197,7 +214,7 @@ static void ConfigureCorsPolicy(CorsPolicyBuilder policy, string[] origins)
|
||||
policy.WithOrigins(origins)
|
||||
.AllowCredentials();
|
||||
}
|
||||
// 1. (空行后) 放行通用 Header 与 Method
|
||||
|
||||
policy
|
||||
.AllowAnyHeader()
|
||||
.AllowAnyMethod();
|
||||
|
||||
Reference in New Issue
Block a user