diff --git a/src/NetEscapades.AspNetCore.SecurityHeaders/ServiceCollectionExtensions.cs b/src/NetEscapades.AspNetCore.SecurityHeaders/ServiceCollectionExtensions.cs index e8e0eef..c3afc44 100644 --- a/src/NetEscapades.AspNetCore.SecurityHeaders/ServiceCollectionExtensions.cs +++ b/src/NetEscapades.AspNetCore.SecurityHeaders/ServiceCollectionExtensions.cs @@ -13,7 +13,7 @@ public static class ServiceCollectionExtensions /// Creates a builder for configuring security header policies. /// /// The to add services to. - /// The so that additional calls can be chained. + /// The so that header policies can be configured. public static SecurityHeaderPolicyBuilder AddSecurityHeaderPolicies(this IServiceCollection services) { if (services == null) @@ -25,4 +25,35 @@ public static SecurityHeaderPolicyBuilder AddSecurityHeaderPolicies(this IServic services.AddSingleton(options); return new SecurityHeaderPolicyBuilder(options); } + + /// + /// Creates a builder for configuring security header policies. + /// + /// The to add services to. + /// A configuration method that provides access to an + /// to configure your header policies + /// The so that additional calls can be chained. + public static IServiceCollection AddSecurityHeaderPolicies( + this IServiceCollection services, + Action configure) + { + if (services == null) + { + throw new ArgumentNullException(nameof(services)); + } + + if (configure == null) + { + throw new ArgumentNullException(nameof(configure)); + } + + var options = new CustomHeaderOptions(); + services.AddSingleton(provider => + { + configure(new SecurityHeaderPolicyBuilder(options), provider); + return options; + }); + + return services; + } } \ No newline at end of file diff --git a/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt b/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt index fa5739c..d9848a8 100644 --- a/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt +++ b/test/NetEscapades.AspNetCore.SecurityHeaders.Test/PublicApiTest.PublicApiHasNotChanged.verified.txt @@ -294,6 +294,7 @@ namespace Microsoft.Extensions.DependencyInjection public static class ServiceCollectionExtensions { public static NetEscapades.AspNetCore.SecurityHeaders.Infrastructure.SecurityHeaderPolicyBuilder AddSecurityHeaderPolicies(this Microsoft.Extensions.DependencyInjection.IServiceCollection services) { } + public static Microsoft.Extensions.DependencyInjection.IServiceCollection AddSecurityHeaderPolicies(this Microsoft.Extensions.DependencyInjection.IServiceCollection services, System.Action configure) { } } } namespace NetEscapades.AspNetCore.SecurityHeaders.Headers.ContentSecurityPolicy diff --git a/test/NetEscapades.AspNetCore.SecurityHeaders.Test/SecurityHeadersMiddlewareTests.cs b/test/NetEscapades.AspNetCore.SecurityHeaders.Test/SecurityHeadersMiddlewareTests.cs index 2876fdd..9002bef 100644 --- a/test/NetEscapades.AspNetCore.SecurityHeaders.Test/SecurityHeadersMiddlewareTests.cs +++ b/test/NetEscapades.AspNetCore.SecurityHeaders.Test/SecurityHeadersMiddlewareTests.cs @@ -2355,6 +2355,41 @@ public async Task HttpRequest_CanApplyDifferentPolicyBasedOnResponseContentType( response.Headers.AssertHttpRequestDefaultSecurityHeaders(); } + [Fact] + public async Task HttpRequest_CanUseProviderToConfigurePolicies() + { + // Arrange + var hostBuilder = new WebHostBuilder() + .ConfigureServices(s => + { + s.AddSingleton(); + s.AddSecurityHeaderPolicies((builder, provider) => + { + var service = provider.GetRequiredService(); + builder.SetDefaultPolicy(service.GetPolicy(null)); + }); + }) + .Configure(app => + { + app.UseSecurityHeaders(); + app.Run(async context => + { + context.Response.ContentType = "text/html"; + await context.Response.WriteAsync("Test response"); + }); + }); + + using (var server = new TestServer(hostBuilder)) + { + // Act + // Add header + var response = await server.CreateRequest("/") + .SendAsync("PUT"); + response.EnsureSuccessStatusCode(); + response.Headers.Should().ContainKey("Custom-Header").WhoseValue.Should().Contain("Default"); + } + } + private class HeaderPolicyCollectionFactory { private readonly HeaderPolicyCollection _default = new HeaderPolicyCollection().AddCustomHeader("Custom-Header", "Default");