197 lines
7.2 KiB
C#
197 lines
7.2 KiB
C#
using Fake.AspNetCore;
|
||
using Fake.AspNetCore.Auditing;
|
||
using Fake.AspNetCore.Authentication;
|
||
using Fake.AspNetCore.ExceptionHandling;
|
||
using Fake.AspNetCore.Newtonsoft;
|
||
using Fake.AspNetCore.Swagger;
|
||
using Fake.Autofac;
|
||
using Fake.FeiShu;
|
||
using Fake.Json;
|
||
using Fake.Messaging.Dashboard;
|
||
using Fake.Modularity;
|
||
using Fake.Security.Claims;
|
||
using Fake.Serilog;
|
||
using FluentValidation.AspNetCore;
|
||
using Hangfire;
|
||
using Microsoft.AspNetCore.Authorization;
|
||
using Microsoft.AspNetCore.HttpOverrides;
|
||
using Microsoft.AspNetCore.Mvc.Authorization;
|
||
using OpenTelemetry.Resources;
|
||
using OpenTelemetry.Trace;
|
||
using TrackCenter.Application;
|
||
using TrackCenter.Application.Hangfire;
|
||
using TrackCenter.Repository;
|
||
using TrackCenter.Repository.Otel;
|
||
using TrackCenter.Repository.Otel.Options;
|
||
using TrackCenter.Application.Filters;
|
||
|
||
namespace TrackCenter.Api;
|
||
|
||
[DependsOn(typeof(FakeAutofacModule))]
|
||
[DependsOn(typeof(FakeAspNetCoreModule))]
|
||
[DependsOn(typeof(TrackCenterApplicationModule))]
|
||
[DependsOn(typeof(TrackCenterRepositoryModule))]
|
||
[DependsOn(typeof(FakeMessagingDashboardModule))]
|
||
[DependsOn(typeof(FakeSerilogModule))]
|
||
public class TrackCenterApiModule : FakeModule
|
||
{
|
||
private const string DefaultCorsPolicyName = "default";
|
||
|
||
public override void PreConfigureServices(ServiceConfigurationContext context)
|
||
{
|
||
FakeClaimTypes.UserId = "mapId";
|
||
}
|
||
|
||
public override void ConfigureServices(ServiceConfigurationContext context)
|
||
{
|
||
var services = context.Services;
|
||
var configuration = context.Services.GetConfiguration();
|
||
|
||
services.Configure<FakeAspNetCoreMvcOptions>(options =>
|
||
{
|
||
options.ApplicationServices2Controller<TrackCenterApplicationModule>();
|
||
});
|
||
|
||
// 配置签名验证选项
|
||
services.Configure<SignatureValidationOptions>(configuration.GetSection("SignatureValidation"));
|
||
|
||
// 全局授权配置:所有接口默认需要授权
|
||
services.AddMvc(options =>
|
||
{
|
||
var policy = new AuthorizationPolicyBuilder()
|
||
.RequireAuthenticatedUser()
|
||
.Build();
|
||
options.Filters.Add(new AuthorizeFilter(policy));
|
||
// 添加签名验证过滤器
|
||
options.Filters.Add<SignatureValidationFilter>();
|
||
}).AddNewtonsoftJson();
|
||
|
||
//Json格式化全局处理
|
||
services.Configure<FakeJsonSerializerOptions>(options =>
|
||
{
|
||
options.InputDateTimeFormats.Add("yyyy-MM-dd HH:mm:ss");
|
||
options.LongToString = true;
|
||
});
|
||
context.Services.AddFakeNewtonsoft();
|
||
|
||
services.AddFakeSwaggerGen(addSecurity:true)
|
||
.AddFakeAspNetCoreAuditing()
|
||
.AddFeiShuNotification();
|
||
|
||
services.AddFluentValidationAutoValidation().AddFluentValidationClientsideAdapters();
|
||
|
||
var otelOptions = new OTelOptions()
|
||
{
|
||
EnableAspNetCore = true,
|
||
EnableHttpClient = true,
|
||
EnableSql = true
|
||
};
|
||
configuration.GetSection("OTel").Bind(otelOptions);
|
||
ActivityHelper.InitActivitySource(otelOptions);
|
||
services.AddOpenTelemetry()
|
||
.ConfigureResource(resource => resource.AddService(otelOptions.ServiceName))
|
||
.WithTracing(tracing =>
|
||
{
|
||
switch (otelOptions.SamplerType)
|
||
{
|
||
case SamplerType.AlwaysOn:
|
||
tracing.SetSampler(new AlwaysOnSampler());
|
||
break;
|
||
case SamplerType.AlwaysOff:
|
||
tracing.SetSampler(new AlwaysOffSampler());
|
||
break;
|
||
case SamplerType.ParentBasedSampler:
|
||
{
|
||
Sampler childSampler = otelOptions.ChildBasedSampler switch
|
||
{
|
||
SamplerType.AlwaysOn => new AlwaysOnSampler(),
|
||
SamplerType.AlwaysOff => new AlwaysOffSampler(),
|
||
SamplerType.TraceIdRatio =>
|
||
new TraceIdRatioBasedSampler(otelOptions.SamplerProbability),
|
||
_ => new AlwaysOnSampler(),
|
||
};
|
||
tracing.SetSampler(new ParentBasedSampler(childSampler));
|
||
}
|
||
break;
|
||
case SamplerType.TraceIdRatio:
|
||
tracing.SetSampler(new TraceIdRatioBasedSampler(otelOptions.SamplerProbability));
|
||
break;
|
||
default:
|
||
tracing.SetSampler(new AlwaysOnSampler());
|
||
break;
|
||
}
|
||
|
||
tracing.AddSource(otelOptions.ServiceName);
|
||
});
|
||
|
||
services.AddCors(options =>
|
||
{
|
||
options.AddPolicy(DefaultCorsPolicyName, builder =>
|
||
{
|
||
builder.WithOrigins(configuration.GetSection("App:CorsOrigins").Get<string[]>() ?? [])
|
||
.AllowAnyHeader()
|
||
.AllowAnyMethod()
|
||
.AllowCredentials();
|
||
});
|
||
});
|
||
|
||
services.AddFakeJwtAuthentication();
|
||
|
||
// 添加授权服务
|
||
services.AddAuthorization();
|
||
|
||
services.Configure<ForwardedHeadersOptions>(options =>
|
||
{
|
||
// 反向代理场景下恢复客户端真实来源信息,供 Swagger、鉴权和重定向等中间件使用
|
||
options.ForwardedHeaders = ForwardedHeaders.XForwardedFor |
|
||
ForwardedHeaders.XForwardedProto |
|
||
ForwardedHeaders.XForwardedHost;
|
||
options.KnownNetworks.Clear();
|
||
options.KnownProxies.Clear();
|
||
});
|
||
}
|
||
|
||
public override void ConfigureApplication(ApplicationConfigureContext context)
|
||
{
|
||
var app = context.GetWebApplication();
|
||
var configuration = context.GetConfiguration();
|
||
|
||
// 必须在读取 Scheme/Host/PathBase 的中间件之前执行,否则 Swagger 会生成错误的请求地址
|
||
app.UseForwardedHeaders();
|
||
|
||
app.Use(async (httpContext, next) =>
|
||
{
|
||
httpContext.Request.EnableBuffering();
|
||
await next.Invoke();
|
||
});
|
||
|
||
// 虚拟路由-网关适配
|
||
app.UsePathBase(app.Configuration["ASPNETCORE_PATHBASE"]);
|
||
|
||
app.UseFakeExceptionHandling();
|
||
|
||
app.MapControllers();
|
||
// Configure the HTTP request pipeline.
|
||
app.UseFakeSwagger();
|
||
|
||
app.UseRouting();
|
||
|
||
app.UseCors(DefaultCorsPolicyName);
|
||
|
||
app.UseHangfireDashboard("/hangfire", new DashboardOptions
|
||
{
|
||
DisplayStorageConnectionString = false,
|
||
IgnoreAntiforgeryToken = true,
|
||
// 「返回站点」链接;PathBase 已由 UsePathBase 处理,勿再设 PrefixPath,否则会变成 /track/track/hangfire/...
|
||
AppPath = configuration["ASPNETCORE_PATHBASE"],
|
||
DashboardTitle = "轨迹预警任务",
|
||
Authorization = [new AnonymousHangfireAuthorizationFilter()]
|
||
});
|
||
|
||
// 必须在 UsePathBase 之后:完整对外路径为 {PathBase}/eventbus
|
||
app.UseFakeMessagingDashboard();
|
||
|
||
app.Services.GetRequiredService<IFeiShuNotificationService>().Send("Application started");
|
||
}
|
||
}
|