using Azure.Storage.Blobs; using Microsoft.ApplicationInsights.Extensibility; using Microsoft.AspNetCore; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.DataProtection; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Http.Features; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Localization; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Infrastructure; using Microsoft.AspNetCore.Mvc.ViewFeatures; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.IdentityModel.Tokens; using System; using System.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http.Headers; using System.Text; using System.Threading.Tasks; using gehGassi.Common; using gehGassi.Core.Interfaces; using gehGassi.Core.Services; using gehGassi.Domain.Localization; using gehGassi.Domain.Roles; using gehGassi.Domain.Users; using gehGassi.External.Services; using gehGassi.Persistence; using gehGassi.Pwned; using gehGassi.Web.Auth; using gehGassi.Web.Auth.AuthorizationHandlers; using gehGassi.Web.Auth.Requirements; using gehGassi.Web.Helper; using gehGassi.Web.Hubs; using gehGassi.Web.Services; using Microsoft.Graph; using Newtonsoft.Json; using BackgroundService = gehGassi.Web.BackgroundServices.BackgroundService; using WebApplication = Microsoft.AspNetCore.Builder.WebApplication; using Microsoft.Graph.Models; using Asp.Versioning; using Swashbuckle.AspNetCore.SwaggerGen; using gehGassi.Web.Controllers.WebsiteApi; using gehGassi.Klarna.Checkout; var builder = WebApplication.CreateBuilder(args); if (builder.Environment.EnvironmentName == "Live") { builder.Logging.AddAzureWebAppDiagnostics(); } var defaultCulture = builder.Configuration.GetSection("LocalizationOptions")?["DefaultCulture"].ToString(); var availableLanguages = builder.Configuration.GetSection("LocalizationOptions")?["Languages"].ToString(); var sessionTimeout = int.Parse(builder.Configuration.GetSection("SessionSettings")?["ClientTimeOut"]); var sessionTimeoutBackend = int.Parse(builder.Configuration.GetSection("SessionSettings")?["TimeOut"]); //Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("ORg4AjUWIQA/Gnt2VVhjQlFac1lJXGFWfVJpTGpQdk5xdV9DaVZUTWY/P1ZhSXxRd0RiXX5cdHxRR2JZWEY=;NRAiBiAaIQQuGjN/V0Z+X09EaFpEVmJLYVB3WmpQdldgdVRMZVVbQX9PIiBoS35RdERiWHtfcnBdQmFeVkZ0;Mgo+DSMBMAY9C3t2VVhjQlFac1lJXGFWfVJpTGpQdk5xdV9DaVZUTWY/P1ZhSXxRd0RiXX5cdHxRR2JUVEY="); //Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("ORg4AjUWIQA/Gnt2VVhkQlFacltJXGFWfVJpTGpQdk5xdV9DaVZUTWY/P1ZhSXxQdkRhXX9Xc3NQQmFYWUc=;NRAiBiAaIQQuGjN/V0Z+WE9EaFtGVmJLYVB3WmpQdldgdVRMZVVbQX9PIiBoS35RdUViW3teeXdSQ2RdV0F1;Mgo+DSMBMAY9C3t2VVhkQlFacltJXGFWfVJpTGpQdk5xdV9DaVZUTWY/P1ZhSXxQdkRhXX9Xc3NQQmJdWUc="); //Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("NRAiBiAaIQQuGjN/V0J+XU9Ad1RDX3xKf0x/TGpQb19xflBPallYVBYiSV9jS3pTd0RqWXpcdnZRRGVVUA==;Mgo+DSMBMAY9C3t2UVhhQlVFfV5AQmBIYVp/TGpJfl96cVxMZVVBJAtUQF1hTX5Sd0xjXH1YcnBXQWRb"); Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Ngo9BigBOggjHTQxAR8/V1NHaF5cWWdCf1FpRmJGdld5fUVHYVZUTXxaS00DNHVRdkdnWX5feXRQQ2NcUUx+Vko="); builder.Services.Configure(options => { // This lambda determines whether user consent for non-essential cookies is needed for a given request. options.CheckConsentNeeded = context => true; options.MinimumSameSitePolicy = SameSiteMode.None; options.Secure = CookieSecurePolicy.Always; }); builder.Services.AddDbContext(options => options.UseSqlServer(builder.Configuration.GetConnectionString("SqlDbContext"), sqlOptions => sqlOptions.UseNetTopologySuite().MigrationsAssembly(typeof(SqlDbContext).Assembly.GetName().Name))); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.TryAddSingleton(); builder.Services.TryAddSingleton(); builder.Services.AddSingleton(); builder.Services.Configure(o => { var supportedCultures = new List(); foreach (var lang in availableLanguages.Split(",")) { supportedCultures.Add(new CultureInfo(lang)); } o.DefaultRequestCulture = new RequestCulture(new CultureInfo(defaultCulture)); // Formatting numbers, dates, etc. o.SupportedCultures = supportedCultures; // UI strings that we have localized. o.SupportedUICultures = supportedCultures; o.RequestCultureProviders.Clear(); o.RequestCultureProviders = new List { // Order is important, its in which order they will be evaluated new RouteValueRequestCultureProvider(){Options = o}, new CookieRequestCultureProvider(), new QueryStringRequestCultureProvider(), new AcceptLanguageHeaderRequestCultureProvider() }; //var requestProvider = o.RequestCultureProviders.OfType().FirstOrDefault(); //if (requestProvider != null) // o.RequestCultureProviders.Remove(requestProvider); }); //Statische Variable als Hilfe für "ILocalizable" und LocalizableBase LocalizableHelper.DefaultLanguage = defaultCulture; LocalizableHelper.Languages = availableLanguages; CultureInfo.DefaultThreadCurrentCulture = new CultureInfo(defaultCulture); CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo(defaultCulture); builder.Services.Configure(builder.Configuration.GetSection("LocalizationOptions")); builder.Services.Configure(builder.Configuration.GetSection("EmailSenderOptions")); builder.Services.Configure(builder.Configuration.GetSection("LicenseOptions")); builder.Services.Configure(builder.Configuration.GetSection("AuthOptions")); builder.Services.Configure(builder.Configuration.GetSection("SessionSettings")); builder.Services.Configure(builder.Configuration.GetSection("SystemJsOptions")); builder.Services.Configure(builder.Configuration.GetSection("AuditOptions")); builder.Services.Configure(builder.Configuration.GetSection("VatValidation")); builder.Services.Configure(builder.Configuration.GetSection("ApplicationInsightsOptions")); builder.Services.Configure(builder.Configuration.GetSection("fido2")); builder.Services.Configure(builder.Configuration.GetSection("JWT")); builder.Services.Configure(builder.Configuration.GetSection("FileServiceModeOptions")); builder.Services.Configure(builder.Configuration.GetSection("WebJobApi")); builder.Services.Configure(builder.Configuration.GetSection("CachingOptions")); builder.Services.Configure(builder.Configuration.GetSection("BackgroundServiceOptions")); builder.Services.Configure(builder.Configuration.GetSection("GeoLocationOptions")); builder.Services.Configure(builder.Configuration.GetSection("ListingOptions")); builder.Services.Configure(builder.Configuration.GetSection("ShopOptions")); builder.Services.Configure(builder.Configuration.GetSection("AppleOptions")); builder.Services.Configure(builder.Configuration.GetSection("MangoPayOptions")); builder.Services.Configure(builder.Configuration.GetSection("PushNotificationOptions")); builder.Services.Configure(builder.Configuration.GetSection("WalkComplaintOptions")); builder.Services.Configure(builder.Configuration.GetSection("CoinsOptions")); builder.Services.Configure(builder.Configuration.GetSection("MinCoinsForPot")); builder.Services.AddTransient(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddTransient(); builder.Services.Configure(o => { o.Languages = new List(availableLanguages.Split(",")); o.Directory = "app_files\\countries"; }); builder.Services.AddSingleton(); builder.Services.Configure(o => { o.File = "app_files\\fakemails.csv"; }); builder.Services.AddSingleton(); builder.Services.AddTransient(); var useCloud = bool.Parse(builder.Configuration["FileServiceModeOptions:Cloud"]); if (useCloud) { var azureStorageKey = builder.Configuration["FileServiceModeOptions:AzureStorage"]; builder.Services.AddScoped(s => new AzureBlobFileService(azureStorageKey)); builder.Services.AddScoped(s => new AzureStorageFileShareService(azureStorageKey)); } else { builder.Services.AddScoped(s => new FileService(builder.Environment.WebRootPath + "\\app_files")); builder.Services.AddScoped(s => new LocalFileShareService(builder.Environment.WebRootPath + "\\app_files\\shares")); } builder.Services.AddHttpClient(client => { // Set the base address of the named client. client.BaseAddress = new Uri(builder.Configuration.GetSection("GeoLocationOptions:BaseUri").Value ?? string.Empty); // Add a user-agent default request header. client.DefaultRequestHeaders.UserAgent.Add( new ProductInfoHeaderValue(builder.Configuration.GetSection("GeoLocationOptions:UserAgentName").Value ?? string.Empty, builder.Configuration.GetSection("GeoLocationOptions:UserAgentVersion").Value ?? string.Empty) ); }); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddScoped(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddSingleton(); builder.Services.AddTransient(); //Custom Services here builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddScoped(s => new PlaceHolderService(builder.Environment.WebRootPath + "\\app_files\\placeholders")); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddHostedService(); #region DataProtection var applicationNameForDataProtection = $"gehGassi-{builder.Environment.EnvironmentName}"; if (builder.Environment.IsEnvironment("Production") || builder.Environment.IsEnvironment("Staging") || builder.Environment.IsEnvironment("Live")) { applicationNameForDataProtection = "gehgassi"; } var dataProtectionBuilder = builder.Services.AddDataProtection() .SetApplicationName(applicationNameForDataProtection); var dataProtectionMode = builder.Configuration["DataProtectionOptions:Mode"]; if (dataProtectionMode == "File") dataProtectionBuilder.PersistKeysToFileSystem(new DirectoryInfo($@"{builder.Environment.ContentRootPath}\keys")); else { var client = new BlobServiceClient(builder.Configuration["DataProtectionOptions:AzureStorage"]); var container = client.GetBlobContainerClient("data-protection"); container.CreateIfNotExists(); var blobClient = container.GetBlobClient("keys.xml"); dataProtectionBuilder.PersistKeysToAzureBlobStorage(blobClient); } #endregion builder.Services.AddMemoryCache(); //if (builder.Environment.IsEnvironment("Production") || builder.Environment.IsEnvironment("Staging")) if (builder.Environment.IsEnvironment("Production") || builder.Environment.IsEnvironment("Live")) { builder.Services.AddStackExchangeRedisCache(options => { options.Configuration = builder.Configuration["RedisOptions:ConnectionString"]; options.InstanceName = builder.Configuration["RedisOptions:InstanceName"]; }); } else builder.Services.AddDistributedMemoryCache(); builder.Services.Configure(o => { o.Directory = "app_files\\rolePermissions"; }); builder.Services.AddTransient(); builder.Services.AddPwned(); builder.Services.AddIdentity(c => { c.SignIn.RequireConfirmedEmail = true; c.Password.RequireDigit = false; c.Password.RequireLowercase = false; c.Password.RequireNonAlphanumeric = false; c.Password.RequireUppercase = false; c.Password.RequiredUniqueChars = 0; c.Password.RequiredLength = 12; }).AddEntityFrameworkStores() .AddPwnedPasswordValidator(builder.Configuration) .AddDefaultTokenProviders() .AddTokenProvider>("deleteAccount") .AddErrorDescriber(); builder.Services.Configure(o => { o.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(5); o.Lockout.MaxFailedAccessAttempts = 5; o.Lockout.AllowedForNewUsers = true; }); builder.Services.AddScoped, CustomClaimsPrincipalFactory>(); builder.Services.AddAuthorization(options => { options.AddPolicy(Policies.AdministratorOnly, policy => policy.AddRequirements(new IsInRoleRequirement("Administrator"))); options.AddPolicy(Policies.PowerUserOnly, policy => policy.AddRequirements(new IsInRoleRequirement("Administrator", "PowerUser"))); options.AddPolicy(Policies.CustomerOnly, policy => policy.AddRequirements(new IsInRoleRequirement("Administrator", "PowerUser", "Customer"))); options.AddPolicy(Policies.AppUserOnly, policy => policy.AddRequirements(new IsInRoleRequirement("Administrator", "PowerUser", "AppUser"))); //options.AddPolicy("GivenName", policy => policy.RequireClaim(ClaimTypes.GivenName, "Florian")); //options.AddPolicy("Special", policy => policy.RequireClaim(ClaimTypes.GivenName, "Florian")); }); builder.Services.AddSingleton(); builder.Services.AddSingleton(); builder.Services.AddSingleton, ConfigureCookieAuthenticationOptions>(); builder.Services.AddScoped(); builder.Services.ConfigureApplicationCookie(o => { o.Cookie.Name = "gehGassiCookie"; o.LoginPath = $"/{CultureInfo.CurrentCulture.TwoLetterISOLanguageName}/account/login"; o.AccessDeniedPath = $"/{CultureInfo.CurrentCulture.TwoLetterISOLanguageName}/account/accessdenied"; o.LogoutPath = $"/{CultureInfo.CurrentCulture.TwoLetterISOLanguageName}/account/Logout"; o.EventsType = typeof(LocalizedCookieAuthenticationEvents); //o.Cookie.Expiration = TimeSpan.FromDays(30); o.ExpireTimeSpan = TimeSpan.FromMinutes(sessionTimeoutBackend); o.SlidingExpiration = true; o.Cookie.SecurePolicy = CookieSecurePolicy.Always; }); builder.Services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme) .AddJwtBearer(o => { o.SaveToken = true; o.TokenValidationParameters = new TokenValidationParameters() { ValidAudience = builder.Configuration["JWT:ValidAudience"], ValidIssuer = builder.Configuration["JWT:ValidIssuer"], IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["JWT:Secret"])) }; o.Events = new JwtBearerEvents { OnAuthenticationFailed = context => { context.NoResult(); context.Response.StatusCode = StatusCodes.Status401Unauthorized; return Task.CompletedTask; }, OnMessageReceived = context => { var accessToken = context.Request.Query["access_token"]; // If the request is for our hub... var path = context.HttpContext.Request.Path; if (!string.IsNullOrEmpty(accessToken) && (path.StartsWithSegments("/appHub"))) { // Read the token out of the query string context.Token = accessToken; } return Task.CompletedTask; } }; }) .AddGoogle(g => { g.ClientId = builder.Configuration["LoginProvider:Google:ClientId"]; g.ClientSecret = builder.Configuration["LoginProvider:Google:Secret"]; g.SaveTokens = true; }); builder.Services.Configure(x => { //x.ValueLengthLimit = 5000; // Limit on individual form values x.MultipartBodyLengthLimit = 1073741824; // Limit on form body size x.MultipartHeadersLengthLimit = 15728640; // Limit on form header size }); builder.Services.Configure(options => { options.MaxRequestBodySize = 1073741824; // Limit on request body size }); //Register the Permission policy handlers builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddResponseCaching(); //Automapper builder.Services.AddAutoMapper(typeof(Program)); builder.Services.AddCors(options => options.AddPolicy("CorsPolicy", builder => { builder.AllowAnyHeader() .AllowAnyMethod() .SetIsOriginAllowed((host) => true) .AllowCredentials(); })); #if (!DEBUG) builder.Services.AddHttpsRedirection(o => { o.HttpsPort = 443; }); #endif builder.Services.AddSignalR(); builder.Services.AddSession(options => { options.IdleTimeout = TimeSpan.FromMinutes(sessionTimeout); options.Cookie.HttpOnly = true; options.Cookie.IsEssential = true; options.Cookie.SecurePolicy = CookieSecurePolicy.Always; }); var mvc = builder.Services.AddControllersWithViews().AddMvcOptions(options => { options.ModelBinderProviders.Insert(0, new DateTimeModelBinderProvider()); var resourcesCache = int.Parse(builder.Configuration.GetSection("CachingOptions")?["ResourcesCache"]); options.CacheProfiles.Add("ResourcesCache", new CacheProfile() { Duration = resourcesCache, Location = ResponseCacheLocation.Any, VaryByQueryKeys = new[] { "resource", "lang" } }); }) .AddViewLocalization() .AddDataAnnotationsLocalization(o => { o.DataAnnotationLocalizerProvider = (type, factory) => factory.Create("Annotations", "gehGassi.Common"); }) .AddJsonOptions(jo => { jo.JsonSerializerOptions.Converters.Add(new DateTimeOffsetJsonConverter()); jo.JsonSerializerOptions.Converters.Add(new NullableDateTimeOffsetJsonConverter()); jo.JsonSerializerOptions.Converters.Add(new DateOnlyJsonConverter()); jo.JsonSerializerOptions.Converters.Add(new NullableDateOnlyJsonConverter()); }) .AddNewtonsoftJson(jsonOptions => { jsonOptions.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore; jsonOptions.SerializerSettings.DateFormatHandling = Newtonsoft.Json.DateFormatHandling.IsoDateFormat; jsonOptions.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore; jsonOptions.SerializerSettings.Converters.Add(new NetTopologySuite.IO.Converters.GeometryConverter()); //jsonOptions.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); }); #if (DEBUG) mvc.AddRazorRuntimeCompilation(); #endif builder.Services.TryAddSingleton(); builder.Services.AddApplicationInsightsTelemetry(); builder.Services.AddApplicationInsightsTelemetryProcessor(); builder.Services.AddApiVersioning(options => { options.DefaultApiVersion = new ApiVersion(1); options.ReportApiVersions = true; options.AssumeDefaultVersionWhenUnspecified = true; options.ApiVersionReader = ApiVersionReader.Combine( new UrlSegmentApiVersionReader(), new HeaderApiVersionReader("X-Api-Version")); }).AddApiExplorer(options => { options.GroupNameFormat = "'v'V"; options.SubstituteApiVersionInUrl = true; }); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(c => { c.DocumentFilter(); }); var app = builder.Build(); if (app.Environment.EnvironmentName == "Development") { //app.UseSecurityHeaders(policies => // policies // .AddDefaultSecurityHeaders() // .RemoveServerHeader() // .AddContentSecurityPolicy(builder => // { // builder.AddUpgradeInsecureRequests(); // upgrade-insecure-requests // builder.AddBlockAllMixedContent(); // block-all-mixed-content // builder.AddDefaultSrc() // default-src 'self' // .Self(); // builder.AddConnectSrc() // connect-src 'self' // .Self() // .Blob() // .From("https://germanywestcentral-1.in.applicationinsights.azure.com/v2/track") // .From("https://germanywestcentral-1.in.applicationinsights.azure.com//v2/track") // .From("https://dc.services.visualstudio.com/v2/track") // .From("https://app.getsentry.com") // .From("https://noembed.com") // .From("https://*.klarnaevt.com"); ; // builder.AddFontSrc() // font-src 'self' // .Self() // .Data(); // builder.AddObjectSrc() // object-src 'none' // .Self(); // builder.AddFormAction() // form-action 'self' // .Self(); // builder.AddImgSrc() // img-src https: // .Self() // .Data() // .Blob() // .OverHttps(); // builder.AddScriptSrc() // script-src 'self' 'unsafe-inline' 'unsafe-eval' 'report-sample' // .Self() // .UnsafeInline() // .UnsafeEval() // //.From("https://localhost:*") // .From("https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js") // .From("https://*.klarna.com"); // builder.AddStyleSrc() // style-src 'self' 'strict-dynamic' // .Self() // .UnsafeInline(); // builder.AddMediaSrc() // media-src https: // .OverHttps(); // builder.AddFrameSrc() // .Self() // .From("https://*.klarna.com"); // builder.AddFrameAncestors() // frame-ancestors 'none' // .Self(); // builder.AddBaseUri() // base-ri 'self' // .Self(); // }) // ); } else { app.UseSecurityHeaders(policies => policies .AddDefaultSecurityHeaders() .RemoveServerHeader() .AddContentSecurityPolicy(builder => { builder.AddUpgradeInsecureRequests(); // upgrade-insecure-requests builder.AddBlockAllMixedContent(); // block-all-mixed-content builder.AddDefaultSrc() // default-src 'self' .Self(); builder.AddConnectSrc() // connect-src 'self' .Self() .Blob() .From("https://germanywestcentral-1.in.applicationinsights.azure.com/v2/track") .From("https://germanywestcentral-1.in.applicationinsights.azure.com//v2/track") .From("https://dc.services.visualstudio.com/v2/track") .From("https://app.getsentry.com") .From("https://noembed.com") .From("https://*.klarnaevt.com"); builder.AddFontSrc() // font-src 'self' .Self() .Data(); builder.AddObjectSrc() // object-src 'none' .Self(); builder.AddFormAction() // form-action 'self' .Self(); builder.AddImgSrc() // img-src https: .Self() .Data() .Blob() .OverHttps(); builder.AddScriptSrc() // script-src 'self' 'unsafe-inline' 'unsafe-eval' 'report-sample' .Self() .UnsafeInline() .UnsafeEval() .From("https://js.monitor.azure.com/scripts/b/ai.2.min.js") .From("https://az416426.vo.msecnd.net/scripts/b/ai.2.min.js") .From("https://*.klarna.com"); builder.AddStyleSrc() // style-src 'self' 'strict-dynamic' .Self() .UnsafeInline(); builder.AddMediaSrc() // media-src https: .OverHttps(); builder.AddFrameSrc() .Self() .From("https://*.klarna.com"); builder.AddFrameAncestors() // frame-ancestors 'none' .Self(); builder.AddBaseUri() // base-ri 'self' .Self(); }) ); } var localizationOptions = app.Services.GetService>(); var locOptions = app.Services.GetService>(); var appInsightOptions = app.Services.GetService>(); app.UseRequestLocalization(locOptions.Value); if (!appInsightOptions.Value.IsEnabled) { var telemetryConfig = app.Services.GetService(); telemetryConfig.DisableTelemetry = true; } if (app.Environment.IsDevelopment() == false) { app.UseMiddleware(); } app.UseSwagger(); app.UseSwaggerUI(o => { o.DefaultModelsExpandDepth(-1); }); app.MapSwagger().RequireAuthorization(); if (app.Environment.IsDevelopment()) { app.UseDeveloperExceptionPage(); //app.UseDatabaseErrorPage(); } else { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseStatusCodePages(async context => { if (context.HttpContext.Response.StatusCode == 405) { context.HttpContext.Response.StatusCode = 404; } //Ajax-Requests werden anders behandelt! if (!context.HttpContext.Request.IsAjaxRequest()) { if (context.HttpContext.Response.StatusCode is >= 401 and <= 405) { var currentCulture = CultureInfo.CurrentCulture.TwoLetterISOLanguageName; var newPath = $"/{currentCulture}/Home/Status{context.HttpContext.Response.StatusCode}"; context.HttpContext.Response.Redirect(newPath); } else { await context.Next(context.HttpContext); } //context.HttpContext.Request.Path = newPath; //await context.Next(context.HttpContext); } }); using (var scope = app.Services.CreateScope()) { var services = scope.ServiceProvider; try { var dbInitializer = services.GetRequiredService(); var success = await dbInitializer.SeedAsync(); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.Message); } } if (!app.Environment.IsDevelopment()) { app.UseHttpsRedirection(); } app.UseStaticFiles(new StaticFileOptions() { OnPrepareResponse = context => { var cachingLib = int.Parse(app.Configuration.GetSection("CachingOptions")?["Lib"]); var cachingConfig = int.Parse(app.Configuration.GetSection("CachingOptions")?["Config"]); var cachingScripts = int.Parse(app.Configuration.GetSection("CachingOptions")?["Scripts"]); var cachingImages = int.Parse(app.Configuration.GetSection("CachingOptions")?["Images"]); var cachingDefault = int.Parse(app.Configuration.GetSection("CachingOptions")?["Default"]); var isInternetExplorer = false; var userAgent = context.Context.Request.Headers["User-Agent"].FirstOrDefault(); if (userAgent != null) isInternetExplorer = userAgent.ToUpperInvariant().Contains("MSIE") || userAgent.ToUpperInvariant().Contains("TRIDENT"); if (app.Environment.IsDevelopment()) { if (!context.Context.Request.Path.Value.Contains("fonts", StringComparison.OrdinalIgnoreCase) && !isInternetExplorer) //Wegen IE11 Bug context.Context.Response.Headers.Add("Cache-Control", "no-cache, no-store"); else context.Context.Response.Headers.Add("Expires", "-1"); } else { if (context.Context.Request.Path.Value.Contains("/lib/", StringComparison.OrdinalIgnoreCase)) { context.Context.Response.Headers.Append("Cache-Control", $"public,max-age={cachingLib}"); } else if (context.Context.Request.Path.Value.Contains("/config/", StringComparison.OrdinalIgnoreCase)) { context.Context.Response.Headers.Append("Cache-Control", $"public,max-age={cachingConfig}"); } else if (context.Context.Request.Path.Value.Contains("/scripts/", StringComparison.OrdinalIgnoreCase)) { if (context.Context.Request.Path.Value.Contains(".min.js") && !string.IsNullOrWhiteSpace(context.Context.Request.QueryString.Value) && context.Context.Request.QueryString.Value.StartsWith("?v=")) context.Context.Response.Headers.Append("Cache-Control", $"public,max-age={cachingScripts}"); else context.Context.Response.Headers.Add("Cache-Control", "no-cache, no-store"); //context.Context.Response.Headers.Add("Expires", "-1"); } else if (context.Context.Request.Path.Value.Contains("/images/", StringComparison.OrdinalIgnoreCase)) { context.Context.Response.Headers.Append("Cache-Control", $"public,max-age={cachingImages}"); } else { context.Context.Response.Headers.Append("Cache-Control", $"public,max-age={cachingDefault}"); } } } }); app.UseStaticFiles(new StaticFileOptions() { RequestPath = new PathString("/lib") }); //app.UseHttpLogging(); app.UseRouting(); app.UseCookiePolicy(); app.UseResponseCaching(); app.UseAuthentication(); app.UseAuthorization(); app.UseCors("CorsPolicy"); //app.UseSignalR(o => { o.MapHub("/sessionHub"); }); app.UseSession(); app.UseEndpoints(endpoints => { endpoints.MapGet(".well-known/acme-challenge/{id}", async context => { var id = context.Request.RouteValues["id"] as string; var file = Path.Combine(app.Environment.WebRootPath, ".well-known", "acme-challenge", id); await context.Response.SendFileAsync(file); }); endpoints.MapControllerRoute( name: "error", pattern: "{culture=" + localizationOptions.Value.DefaultCulture + "}/Home/Error", new { controller = "Home", action = "Error" }, new { culture = @"^[a-zA-Z]{2}$" }); endpoints.MapControllerRoute (name: "notfound", pattern: "{culture=" + localizationOptions.Value.DefaultCulture + "}/Home/Status404", new { controller = "Home", action = "Status404" }, new { culture = @"^[a-zA-Z]{2}$" }); endpoints.MapControllerRoute (name: "deleteAccount", pattern: "/App/DeleteAccount", new { controller = "App", action = "DeleteAccount" }); //endpoints.MapControllerRoute(name: "api", pattern: "/api/{controller}/{action}/{id}", new{id = RoutePatternParameterKind.Optional}); endpoints.MapControllerRoute( name: "culture", pattern: "{culture=" + localizationOptions.Value.DefaultCulture + "}/{controller=Home}/{action=Index}/{id?}", null, new { culture = @"^[a-zA-Z]{2}$" }); endpoints.MapControllers(); endpoints.MapHub("/systemHub"); endpoints.MapHub("/appHub"); }); app.Run();