diff --git a/src/DefaultBuilder/src/ForwardedHeadersOptionsSetup.cs b/src/DefaultBuilder/src/ForwardedHeadersOptionsSetup.cs index 98835ff05482..f55019e9f115 100644 --- a/src/DefaultBuilder/src/ForwardedHeadersOptionsSetup.cs +++ b/src/DefaultBuilder/src/ForwardedHeadersOptionsSetup.cs @@ -24,7 +24,24 @@ public void Configure(ForwardedHeadersOptions options) return; } - options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; + var forwardedHeaders = _configuration["ForwardedHeaders_Headers"]; + if (string.IsNullOrEmpty(forwardedHeaders)) + { + options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; + } + else + { + var headers = ForwardedHeaders.None; + foreach (var headerName in forwardedHeaders.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)) + { + if (Enum.TryParse(headerName, true, out var headerValue)) + { + headers |= headerValue; + } + } + options.ForwardedHeaders = headers; + } + // Only loopback proxies are allowed by default. Clear that restriction because forwarders are // being enabled by explicit configuration. options.KnownNetworks.Clear(); diff --git a/src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/WebHostTests.cs b/src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/WebHostTests.cs index 8205e1459a08..4f93c6f4050d 100644 --- a/src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/WebHostTests.cs +++ b/src/DefaultBuilder/test/Microsoft.AspNetCore.Tests/WebHostTests.cs @@ -83,6 +83,38 @@ public async Task WebHostConfiguration_EnablesForwardedHeadersFromConfig() result.EnsureSuccessStatusCode(); } + [Fact] + public async Task WebHostConfiguration_EnablesForwardedHeaders_CustomHeaders_FromConfig() + { + using var host = WebHost.CreateDefaultBuilder() + .ConfigureAppConfiguration(configBuilder => + { + configBuilder.AddInMemoryCollection(new[] + { + new KeyValuePair("FORWARDEDHEADERS_ENABLED", "true" ), + new KeyValuePair("FORWARDEDHEADERS_HEADERS", "All" ), + }); + }) + .UseTestServer() + .Configure(app => + { + Assert.True(app.Properties.ContainsKey("ForwardedHeadersAdded"), "Forwarded Headers"); + app.Run(context => + { + Assert.Equal("https", context.Request.Scheme); + Assert.Equal("/test", context.Request.PathBase.Value); + return Task.CompletedTask; + }); + }).Build(); + + await host.StartAsync(); + var client = host.GetTestClient(); + client.DefaultRequestHeaders.Add("x-forwarded-proto", "https"); + client.DefaultRequestHeaders.Add("x-forwarded-prefix", "/test"); + var result = await client.GetAsync("http://localhost/"); + result.EnsureSuccessStatusCode(); + } + [Fact] public void CreateDefaultBuilder_RegistersRouting() {