diff --git a/IssuerDrivingLicense/IssuerDrivingLicense.csproj b/IssuerDrivingLicense/IssuerDrivingLicense.csproj
index de0e688..8892c69 100644
--- a/IssuerDrivingLicense/IssuerDrivingLicense.csproj
+++ b/IssuerDrivingLicense/IssuerDrivingLicense.csproj
@@ -21,8 +21,8 @@
-
-
+
+
diff --git a/IssuerDrivingLicense/Program.cs b/IssuerDrivingLicense/Program.cs
index 0bc8621..1f488ae 100644
--- a/IssuerDrivingLicense/Program.cs
+++ b/IssuerDrivingLicense/Program.cs
@@ -1,18 +1,78 @@
-namespace IssuerDrivingLicense;
+using System.Configuration;
+using IssuerDrivingLicense;
+using IssuerDrivingLicense.Persistence;
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+using Microsoft.AspNetCore.Server.Kestrel.Core;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Identity.Web.UI;
+using Microsoft.Identity.Web;
-public class Program
+var builder = WebApplication.CreateBuilder(args);
+
+builder.WebHost.ConfigureKestrel(serverOptions =>
+{
+ serverOptions.AddServerHeader = false;
+});
+
+var services = builder.Services;
+var configuration = builder.Configuration;
+
+services.Configure(options =>
+{
+ options.AllowSynchronousIO = true;
+});
+
+services.AddSecurityHeaderPolicies()
+ .SetPolicySelector(ctx => SecurityHeadersDefinitions
+ .GetHeaderPolicyCollection(builder.Environment.IsDevelopment()));
+
+services.Configure(configuration.GetSection("CredentialSettings"));
+services.AddScoped();
+services.AddScoped();
+
+services.AddDatabaseDeveloperPageExceptionFilter();
+services.AddDbContext(options =>
+ options.UseSqlServer(
+ configuration.GetConnectionString("DefaultConnection")));
+
+services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
+ .AddMicrosoftIdentityWebApp(configuration.GetSection("AzureAd"));
+
+services.AddAuthorization(options =>
+{
+ options.FallbackPolicy = options.DefaultPolicy;
+});
+
+services.AddDistributedMemoryCache();
+
+services.AddRazorPages()
+ .AddMvcOptions(options => { })
+ .AddMicrosoftIdentityUI();
+
+services.AddRazorPages();
+
+var app = builder.Build();
+
+app.UseSecurityHeaders();
+
+if (app.Environment.IsDevelopment())
+{
+ app.UseDeveloperExceptionPage();
+}
+else
{
- public static void Main(string[] args)
- {
- CreateHostBuilder(args).Build().Run();
- }
-
- public static IHostBuilder CreateHostBuilder(string[] args) =>
- Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder
- .ConfigureKestrel(options => options.AddServerHeader = false)
- .UseStartup();
- });
+ app.UseExceptionHandler("/Error");
}
+
+app.UseHttpsRedirection();
+app.UseStaticFiles();
+
+app.UseRouting();
+
+app.UseAuthentication();
+app.UseAuthorization();
+
+app.MapRazorPages();
+app.MapControllers();
+
+app.Run();
diff --git a/IssuerDrivingLicense/SecurityHeadersDefinitions.cs b/IssuerDrivingLicense/SecurityHeadersDefinitions.cs
index d5ffdeb..99ee508 100644
--- a/IssuerDrivingLicense/SecurityHeadersDefinitions.cs
+++ b/IssuerDrivingLicense/SecurityHeadersDefinitions.cs
@@ -2,13 +2,22 @@ namespace IssuerDrivingLicense;
public static class SecurityHeadersDefinitions
{
+ private static HeaderPolicyCollection? policy;
+
public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
{
- var policy = new HeaderPolicyCollection()
+ // Avoid building a new HeaderPolicyCollection on every request for performance reasons.
+ // Where possible, cache and reuse HeaderPolicyCollection instances.
+ if (policy != null)
+ {
+ return policy;
+ }
+
+ policy = new HeaderPolicyCollection()
.AddFrameOptionsDeny()
- .AddXssProtectionBlock()
.AddContentTypeOptionsNoSniff()
.AddReferrerPolicyStrictOriginWhenCrossOrigin()
+ .RemoveServerHeader()
.AddCrossOriginOpenerPolicy(builder => builder.SameOrigin())
.AddCrossOriginEmbedderPolicy(builder => builder.RequireCorp())
.AddCrossOriginResourcePolicy(builder => builder.SameOrigin())
@@ -17,32 +26,14 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
builder.AddObjectSrc().None();
builder.AddBlockAllMixedContent();
builder.AddImgSrc().Self().From("data:");
- builder.AddFormAction().Self();
builder.AddFontSrc().Self();
+ builder.AddFormAction().Self();
builder.AddStyleSrc().Self().UnsafeInline();
builder.AddBaseUri().Self();
- builder.AddScriptSrc().Self().UnsafeInline().WithNonce();
+ builder.AddScriptSrc().UnsafeInline().WithNonce();
builder.AddFrameAncestors().None();
- //builder.AddCustomDirective("require-trusted-types-for", "'script'");
})
- .RemoveServerHeader()
- .AddPermissionsPolicy(builder =>
- {
- builder.AddAccelerometer().None();
- builder.AddAutoplay().None();
- builder.AddCamera().None();
- builder.AddEncryptedMedia().None();
- builder.AddFullscreen().All();
- builder.AddGeolocation().None();
- builder.AddGyroscope().None();
- builder.AddMagnetometer().None();
- builder.AddMicrophone().None();
- builder.AddMidi().None();
- builder.AddPayment().None();
- builder.AddPictureInPicture().None();
- builder.AddSyncXHR().None();
- builder.AddUsb().None();
- });
+ .AddPermissionsPolicyWithDefaultSecureDirectives();
if (!isDev)
{
@@ -50,8 +41,6 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
policy.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365);
}
- policy.ApplyDocumentHeadersToAllResponses();
-
return policy;
}
}
diff --git a/IssuerDrivingLicense/Startup.cs b/IssuerDrivingLicense/Startup.cs
deleted file mode 100644
index 06f47c1..0000000
--- a/IssuerDrivingLicense/Startup.cs
+++ /dev/null
@@ -1,78 +0,0 @@
-using IssuerDrivingLicense.Persistence;
-using Microsoft.AspNetCore.Authentication.OpenIdConnect;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.Identity.Web;
-using Microsoft.Identity.Web.UI;
-
-namespace IssuerDrivingLicense;
-
-public class Startup
-{
- public Startup(IConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- public IConfiguration Configuration { get; }
-
- public void ConfigureServices(IServiceCollection services)
- {
- services.Configure(options =>
- {
- options.AllowSynchronousIO = true;
- });
-
- services.Configure(Configuration.GetSection("CredentialSettings"));
- services.AddScoped();
- services.AddScoped();
-
- services.AddDatabaseDeveloperPageExceptionFilter();
- services.AddDbContext(options =>
- options.UseSqlServer(
- Configuration.GetConnectionString("DefaultConnection")));
-
- services.AddAuthentication(OpenIdConnectDefaults.AuthenticationScheme)
- .AddMicrosoftIdentityWebApp(Configuration.GetSection("AzureAd"));
-
- services.AddAuthorization(options =>
- {
- options.FallbackPolicy = options.DefaultPolicy;
- });
-
- services.AddDistributedMemoryCache();
-
- services.AddRazorPages()
- .AddMvcOptions(options => { })
- .AddMicrosoftIdentityUI();
- }
-
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- app.UseSecurityHeaders(SecurityHeadersDefinitions
- .GetHeaderPolicyCollection(env.IsDevelopment()));
-
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- else
- {
- app.UseExceptionHandler("/Error");
- }
-
- app.UseHttpsRedirection();
- app.UseStaticFiles();
-
- app.UseRouting();
-
- app.UseAuthentication();
- app.UseAuthorization();
-
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapRazorPages();
- endpoints.MapControllers();
- });
- }
-}
diff --git a/VerifierInsuranceCompany/Program.cs b/VerifierInsuranceCompany/Program.cs
index 2877105..8a6ecaa 100644
--- a/VerifierInsuranceCompany/Program.cs
+++ b/VerifierInsuranceCompany/Program.cs
@@ -1,16 +1,59 @@
-namespace VerifierInsuranceCompany;
+using System.Configuration;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Authentication.OpenIdConnect;
+using Microsoft.AspNetCore.Server.Kestrel.Core;
+using VerifierInsuranceCompany;
-public class Program
+var builder = WebApplication.CreateBuilder(args);
+
+builder.WebHost.ConfigureKestrel(serverOptions =>
+{
+ serverOptions.AddServerHeader = false;
+});
+
+var services = builder.Services;
+var configuration = builder.Configuration;
+
+services.Configure(options =>
+{
+ options.AllowSynchronousIO = true;
+});
+
+services.AddSecurityHeaderPolicies()
+ .SetPolicySelector(ctx => SecurityHeadersDefinitions
+ .GetHeaderPolicyCollection(builder.Environment.IsDevelopment()));
+
+services.AddScoped();
+services.Configure(options =>
+{
+ options.AllowSynchronousIO = true;
+});
+
+services.Configure(configuration.GetSection("CredentialSettings"));
+services.AddHttpClient();
+services.AddDistributedMemoryCache();
+
+services.AddRazorPages();
+
+var app = builder.Build();
+
+app.UseSecurityHeaders();
+
+if (app.Environment.IsDevelopment())
{
- public static void Main(string[] args)
- {
- CreateHostBuilder(args).Build().Run();
- }
-
- public static IHostBuilder CreateHostBuilder(string[] args) =>
- Host.CreateDefaultBuilder(args)
- .ConfigureWebHostDefaults(webBuilder =>
- {
- webBuilder.UseStartup();
- });
+ app.UseDeveloperExceptionPage();
}
+else
+{
+ app.UseExceptionHandler("/Error");
+ app.UseHsts();
+}
+
+app.UseHttpsRedirection();
+app.UseStaticFiles();
+app.UseRouting();
+
+app.MapControllers();
+app.MapRazorPages();
+
+app.Run();
diff --git a/VerifierInsuranceCompany/SecurityHeadersDefinitions.cs b/VerifierInsuranceCompany/SecurityHeadersDefinitions.cs
index 72b589a..efc2d8a 100644
--- a/VerifierInsuranceCompany/SecurityHeadersDefinitions.cs
+++ b/VerifierInsuranceCompany/SecurityHeadersDefinitions.cs
@@ -1,14 +1,23 @@
-namespace IssuerDrivingLicense;
+namespace VerifierInsuranceCompany;
public static class SecurityHeadersDefinitions
{
+ private static HeaderPolicyCollection? policy;
+
public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
{
- var policy = new HeaderPolicyCollection()
+ // Avoid building a new HeaderPolicyCollection on every request for performance reasons.
+ // Where possible, cache and reuse HeaderPolicyCollection instances.
+ if (policy != null)
+ {
+ return policy;
+ }
+
+ policy = new HeaderPolicyCollection()
.AddFrameOptionsDeny()
- .AddXssProtectionBlock()
.AddContentTypeOptionsNoSniff()
.AddReferrerPolicyStrictOriginWhenCrossOrigin()
+ .RemoveServerHeader()
.AddCrossOriginOpenerPolicy(builder => builder.SameOrigin())
.AddCrossOriginEmbedderPolicy(builder => builder.RequireCorp())
.AddCrossOriginResourcePolicy(builder => builder.SameOrigin())
@@ -17,32 +26,13 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
builder.AddObjectSrc().None();
builder.AddBlockAllMixedContent();
builder.AddImgSrc().Self().From("data:");
- builder.AddFormAction().Self();
builder.AddFontSrc().Self();
- builder.AddBaseUri().Self();
builder.AddStyleSrc().Self().UnsafeInline();
- builder.AddScriptSrc().Self().UnsafeInline().WithNonce();
+ builder.AddBaseUri().Self();
+ builder.AddScriptSrc().UnsafeInline().WithNonce();
builder.AddFrameAncestors().None();
- //builder.AddCustomDirective("require-trusted-types-for", "'script'");
})
- .RemoveServerHeader()
- .AddPermissionsPolicy(builder =>
- {
- builder.AddAccelerometer().None();
- builder.AddAutoplay().None();
- builder.AddCamera().None();
- builder.AddEncryptedMedia().None();
- builder.AddFullscreen().All();
- builder.AddGeolocation().None();
- builder.AddGyroscope().None();
- builder.AddMagnetometer().None();
- builder.AddMicrophone().None();
- builder.AddMidi().None();
- builder.AddPayment().None();
- builder.AddPictureInPicture().None();
- builder.AddSyncXHR().None();
- builder.AddUsb().None();
- });
+ .AddPermissionsPolicyWithDefaultSecureDirectives();
if (!isDev)
{
@@ -50,8 +40,6 @@ public static HeaderPolicyCollection GetHeaderPolicyCollection(bool isDev)
policy.AddStrictTransportSecurityMaxAgeIncludeSubDomains(maxAgeInSeconds: 60 * 60 * 24 * 365);
}
- policy.ApplyDocumentHeadersToAllResponses();
-
return policy;
}
}
diff --git a/VerifierInsuranceCompany/Startup.cs b/VerifierInsuranceCompany/Startup.cs
deleted file mode 100644
index 3c12bda..0000000
--- a/VerifierInsuranceCompany/Startup.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using IssuerDrivingLicense;
-using Microsoft.AspNetCore.Server.Kestrel.Core;
-
-namespace VerifierInsuranceCompany;
-
-public class Startup
-{
- public Startup(IConfiguration configuration)
- {
- Configuration = configuration;
- }
-
- public IConfiguration Configuration { get; }
-
- // This method gets called by the runtime. Use this method to add services to the container.
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddScoped();
- services.Configure(options =>
- {
- options.AllowSynchronousIO = true;
- });
-
- services.Configure(Configuration.GetSection("CredentialSettings"));
- services.AddHttpClient();
- services.AddDistributedMemoryCache();
-
- services.AddRazorPages();
- }
-
- public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
- {
- app.UseSecurityHeaders(SecurityHeadersDefinitions
- .GetHeaderPolicyCollection(env.IsDevelopment()));
-
- if (env.IsDevelopment())
- {
- app.UseDeveloperExceptionPage();
- }
- else
- {
- app.UseExceptionHandler("/Error");
- app.UseHsts();
- }
-
- app.UseHttpsRedirection();
- app.UseStaticFiles();
- app.UseRouting();
-
- app.UseEndpoints(endpoints =>
- {
- endpoints.MapControllers();
- endpoints.MapRazorPages();
- });
- }
-}
diff --git a/VerifierInsuranceCompany/VerifierInsuranceCompany.csproj b/VerifierInsuranceCompany/VerifierInsuranceCompany.csproj
index 76dbd12..3ae48f7 100644
--- a/VerifierInsuranceCompany/VerifierInsuranceCompany.csproj
+++ b/VerifierInsuranceCompany/VerifierInsuranceCompany.csproj
@@ -14,8 +14,8 @@
-
-
+
+