| | |
| | | using WIDESEAWCS_Server.Filter; |
| | | using WIDESEAWCS_Tasks.OHT; |
| | | using Baidu.Aip.Face; |
| | | using Microsoft.Extensions.FileProviders; |
| | | |
| | | var builder = WebApplication.CreateBuilder(args); |
| | | |
| | |
| | | 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 å¯å¨æå¡ |
| | | |
| | |
| | | builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>()); |
| | | Encoding.RegisterProvider(CodePagesEncodingProvider.Instance); |
| | | |
| | | //è§£å³æå¡å¨å¨HTTPååºä¸èªå¨æ·»å äºä¸äºä¸å¿
è¦çæ 头 |
| | | builder.WebHost.ConfigureKestrel(serverOptions => |
| | | { |
| | | serverOptions.AddServerHeader = false; |
| | | }); |
| | | |
| | | var app = builder.Build(); |
| | | |
| | |
| | | app.UseAllServicesMiddle(builder.Services); |
| | | //FaceAI.Face.sdk_init(null);//人è¸è¯å« |
| | | app.UseSession(); |
| | | //if (app.Environment.IsDevelopment()) |
| | | if (app.Environment.IsDevelopment()) |
| | | { |
| | | //todo |
| | | app.UseSwaggerAuthorized(); |
| | |
| | | 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(); |
| | | |