From 114ffafeeb20ef7066cb2e2882bb58b96f791ab5 Mon Sep 17 00:00:00 2001
From: yanjinhui <3306209981@qq.com>
Date: 星期一, 20 十月 2025 11:33:11 +0800
Subject: [PATCH] 提交数据

---
 项目代码/后端/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs |  110 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 108 insertions(+), 2 deletions(-)

diff --git "a/\351\241\271\347\233\256\344\273\243\347\240\201/\345\220\216\347\253\257/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs" "b/\351\241\271\347\233\256\344\273\243\347\240\201/\345\220\216\347\253\257/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs"
index 75207ae..72e1439 100644
--- "a/\351\241\271\347\233\256\344\273\243\347\240\201/\345\220\216\347\253\257/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs"
+++ "b/\351\241\271\347\233\256\344\273\243\347\240\201/\345\220\216\347\253\257/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs"
@@ -25,6 +25,7 @@
 using WIDESEAWCS_Server.Filter;
 using WIDESEAWCS_Tasks.OHT;
 using Baidu.Aip.Face;
+using Microsoft.Extensions.FileProviders;
 
 var builder = WebApplication.CreateBuilder(args);
 
@@ -47,7 +48,7 @@
 builder.Services.AddMemoryCacheSetup();//缓存
 builder.Services.AddSqlsugarSetup();//SqlSugar 启动服务
 if (AppSettings.GetValue("DBSeedEnable").ObjToBool())
-    builder.Services.AddInitializationHostServiceSetup();//应用初始化服务注入
+    builder.Services.AddInitializationHostServiceSetup();//应用初始化服务注入  创建数据库
 builder.Services.AddHostedService<SeedDataHostedService>();
 builder.Services.AddDbSetup();//Db 启动服务
 
@@ -110,6 +111,11 @@
 builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
 Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
 
+//解决服务器在HTTP响应中自动添加了一些不必要的标头
+builder.WebHost.ConfigureKestrel(serverOptions =>
+{
+    serverOptions.AddServerHeader = false;
+});
 
 var app = builder.Build();
 
@@ -121,7 +127,7 @@
 app.UseAllServicesMiddle(builder.Services);
 //FaceAI.Face.sdk_init(null);//人脸识别
 app.UseSession();
-//if (app.Environment.IsDevelopment())
+if (app.Environment.IsDevelopment())
 {
     //todo
     app.UseSwaggerAuthorized();
@@ -141,6 +147,106 @@
 app.UseDefaultFiles(defaultFilesOptions);
 app.UseMiddleware<HttpRequestMiddleware>();
 app.UseStaticFiles();
+var staticPath = Path.Combine(Directory.GetCurrentDirectory(), "Record");
+if (!Directory.Exists(staticPath))
+{
+    Directory.CreateDirectory(staticPath);
+}
+
+Console.WriteLine($"静态文件路径:{staticPath}");
+
+app.UseStaticFiles(new StaticFileOptions()
+{
+    FileProvider = new PhysicalFileProvider(
+    Path.Combine(Directory.GetCurrentDirectory(), @"Record")),
+    //配置访问虚拟目录时文件夹别名
+    RequestPath = "/Record"
+});
+
+//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.UseCookiePolicy();
 app.UseStatusCodePages();
 

--
Gitblit v1.9.3