yanjinhui
2025-10-20 114ffafeeb20ef7066cb2e2882bb58b96f791ab5
ÏîÄ¿´úÂë/ºó¶Ë/ºǫ́¹ÜÀí/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
@@ -89,7 +89,7 @@
builder.Services.AddControllers(o =>
{
    o.Filters.Add(typeof(GlobalExceptionsFilter));//ȫ���쳣
    o.Filters.Add(typeof(GlobalExceptionsFilter));
})
.AddNewtonsoftJson(options =>
{
@@ -107,6 +107,11 @@
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
//解决服务器在HTTP响应中自动添加了一些不必要的标头
builder.WebHost.ConfigureKestrel(serverOptions =>
{
    serverOptions.AddServerHeader = false;
});
var app = builder.Build();
@@ -118,12 +123,92 @@
app.UseAllServicesMiddle(builder.Services);
//FaceAI.Face.sdk_init(null);//人脸识别
app.UseSession();
//if (app.Environment.IsDevelopment())
if (app.Environment.IsDevelopment())
{
    //todo
    app.UseSwaggerAuthorized();
    app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WIDESEAWCS_Server.index.html") ?? throw new Exception("δ�ҵ�WIDESEAWCS_Server.index.html�ļ�"));
}//�ж��Ƿ���Ҫ��swagger
    app.UseSwaggerMiddle(() => Assembly.GetExecutingAssembly().GetManifestResourceStream("WIDESEAWCS_Server.index.html") ?? throw new Exception("未找到WIDESEAWCS_Server.index.html文件"));
}////判断是否需要打开swagger
//X-Content-Type-Options”头缺失或不安全
// ä½¿ç”¨ AddDefaultSecurityHeaders æ–¹æ³•添加一组推荐的安全标头
app.UseSecurityHeaders(policies => policies
    .AddFrameOptionsDeny() // æ·»åŠ  X-Frame-Options: DENY
    .AddContentTypeOptionsNoSniff() // è¿™å°±æ˜¯ä½ éœ€è¦çš„ X-Content-Type-Options: nosniff
    .AddXssProtectionBlock() // æ·»åŠ  X-XSS-Protection: 1; mode=block
    .AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365) // æ·»åŠ  HSTS å¤´
    // ç§»é™¤æœåŠ¡å™¨ä¿¡æ¯å¤´
    //.AddCustomHeader("X-Powered-By", string.Empty) // æ³¨æ„æ˜¯ AddCustomHeader
    //解决Content-Security-Policy缺失
        .AddContentSecurityPolicy(builder =>
        {
            builder.AddDefaultSrc().Self();
            builder.AddScriptSrc().Self();
            builder.AddStyleSrc().Self();
            builder.AddImgSrc().Self().Data();
            builder.AddFontSrc().Self();
        })
);
// æ‰‹åŠ¨ç§»é™¤å¤šä½™å“åº”å¤´ï¼ˆæ—§ç‰ˆåŒ…å¿…é¡»ï¼‰
app.Use(async (context, next) =>
{
    context.Response.Headers.Remove("Server");
    context.Response.Headers.Remove("X-Powered-By");
    context.Response.Headers.Remove("x-miniprofiler-ids"); // MiniProfiler çš„æŒ‡æ ‡å¤´
    await next();
});
// æ‹¦æˆªæ•æ„Ÿè·¯å¾„,返回 404
app.Use(async (context, next) =>
{
    var path = context.Request.Path.Value ?? string.Empty;
    var blacklist = new[]
    {
        "/.git", "/.svn", "/.env", "/backup", "/backups", "/config", "/database", "/.idea", "/.vscode", "/node_modules"
    };
    if (path.Contains("..") || blacklist.Any(b => path.StartsWith(b, StringComparison.OrdinalIgnoreCase)))
    {
        context.Response.StatusCode = StatusCodes.Status404NotFound;
        await context.Response.WriteAsync("Not Found");
        return;
    }
    await next();
});
//应用程序指标数据暴露
app.Use(async (context, next) =>
{
    var path = context.Request.Path.Value ?? string.Empty;
    // éœ€è¦ä¿æŠ¤çš„端点前缀
    var sensitivePrefixes = new[]
    {
        "/metrics", "/health", "/actuator", "/diagnostics", "/debug", "/metrics/prometheus"
    };
    if (sensitivePrefixes.Any(p => path.StartsWith(p, StringComparison.OrdinalIgnoreCase)))
    {
        var secret = app.Configuration["Internal:MetricsKey"]; // åœ¨ appsettings.json æˆ– çŽ¯å¢ƒå˜é‡é‡Œé…ç½®
        if (string.IsNullOrWhiteSpace(secret))
        {
            // æœªé…ç½®å¯†é’¥ï¼šä¸ºäº†å®‰å…¨æ‹’绝访问
            context.Response.StatusCode = StatusCodes.Status403Forbidden;
            await context.Response.WriteAsync("Forbidden");
            return;
        }
        if (!context.Request.Headers.TryGetValue("X-Internal-Secret", out var provided) || provided != secret)
        {
            context.Response.StatusCode = StatusCodes.Status401Unauthorized;
            await context.Response.WriteAsync("Unauthorized");
            return;
        }
    }
    await next();
});
app.UseHttpsRedirection();
app.UseIpLimitMiddle();
app.UseApiLogMiddleware();