Fixing IPNetwork for .NET 10
This commit is contained in:
@@ -3,7 +3,12 @@ using System.Net;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
#if NET10_0_OR_GREATER
|
||||||
|
using IPNetwork = System.Net.IPNetwork;
|
||||||
|
#else
|
||||||
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
|
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Filters
|
namespace Microsoft.AspNetCore.Mvc.Filters
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,7 +3,12 @@ using System.Net;
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
|
||||||
|
#if NET10_0_OR_GREATER
|
||||||
|
using IPNetwork = System.Net.IPNetwork;
|
||||||
|
#else
|
||||||
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
|
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Mvc.Filters
|
namespace Microsoft.AspNetCore.Mvc.Filters
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,12 @@
|
|||||||
using System.Net;
|
using System.Net;
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.HttpOverrides;
|
using Microsoft.AspNetCore.HttpOverrides;
|
||||||
|
|
||||||
|
#if NET10_0_OR_GREATER
|
||||||
|
using IPNetwork = System.Net.IPNetwork;
|
||||||
|
#else
|
||||||
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
|
using IPNetwork = Microsoft.AspNetCore.HttpOverrides.IPNetwork;
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Builder
|
namespace Microsoft.AspNetCore.Builder
|
||||||
{
|
{
|
||||||
@@ -19,9 +24,9 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
/// A base path (e.g. running in a sub-directory /app) for the application can be defined via <c>ASPNETCORE_APPL_PATH</c> environment variable.
|
/// A base path (e.g. running in a sub-directory /app) for the application can be defined via <c>ASPNETCORE_APPL_PATH</c> environment variable.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// Additionally you can specify the proxy server by using <paramref name="address"/> or a <paramref name="network"/> when there are multiple proxy servers.
|
/// Additionally you can specify the proxy server by using <paramref name="proxyAddress"/> or a <paramref name="proxyNetwork"/> when there are multiple proxy servers.
|
||||||
/// <br/>
|
/// <br/>
|
||||||
/// When neither <paramref name="address"/> nor <paramref name="network"/> is set, the default subnets are configured:
|
/// When neither <paramref name="proxyAddress"/> nor <paramref name="proxyNetwork"/> is set, the default subnets are configured:
|
||||||
/// <list type="bullet">
|
/// <list type="bullet">
|
||||||
/// <item><c>127.0.0.0/8</c></item>
|
/// <item><c>127.0.0.0/8</c></item>
|
||||||
/// <item><c>::1/128</c></item>
|
/// <item><c>::1/128</c></item>
|
||||||
@@ -32,49 +37,108 @@ namespace Microsoft.AspNetCore.Builder
|
|||||||
/// <item><c>fd00::/8</c></item>
|
/// <item><c>fd00::/8</c></item>
|
||||||
/// </list>
|
/// </list>
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
/// <param name="app">The application builder.</param>
|
/// <param name="appBuilder">The application builder.</param>
|
||||||
/// <param name="network">The <see cref="IPNetwork"/> where proxy requests are received from (optional).</param>
|
/// <param name="proxyNetwork">The <see cref="IPNetwork"/> where proxy requests are received from (optional).</param>
|
||||||
/// <param name="address">The <see cref="IPAddress"/> where proxy requests are received from (optional).</param>
|
/// <param name="proxyAddress">The <see cref="IPAddress"/> where proxy requests are received from (optional).</param>
|
||||||
/// <param name="basePath">A custom base path (optional, <c>ASPNETCORE_APPL_PATH</c> is prefererred).</param>
|
/// <param name="basePath">A custom base path (optional, <c>ASPNETCORE_APPL_PATH</c> is prefererred).</param>
|
||||||
public static IApplicationBuilder UseProxyHosting(this IApplicationBuilder app, IPNetwork network = null, IPAddress address = null, string basePath = null)
|
#if NET10_0_OR_GREATER
|
||||||
|
public static IApplicationBuilder UseProxyHosting(this IApplicationBuilder appBuilder, IPNetwork? proxyNetwork = null, IPAddress proxyAddress = null, string basePath = null)
|
||||||
|
#else
|
||||||
|
|
||||||
|
public static IApplicationBuilder UseProxyHosting(this IApplicationBuilder appBuilder, IPNetwork proxyNetwork = null, IPAddress proxyAddress = null, string basePath = null)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
string path = Environment.GetEnvironmentVariable("ASPNETCORE_APPL_PATH");
|
string envPath = Environment.GetEnvironmentVariable("ASPNETCORE_APPL_PATH");
|
||||||
if (string.IsNullOrWhiteSpace(path))
|
string envProxy = Environment.GetEnvironmentVariable("ASPNETCORE_APPL_PROXY");
|
||||||
path = basePath;
|
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(path))
|
if (string.IsNullOrWhiteSpace(envPath))
|
||||||
app.UsePathBase(new PathString(path));
|
envPath = basePath;
|
||||||
|
|
||||||
var options = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All };
|
// Set PathBase from environment variable when available.
|
||||||
options.KnownProxies.Clear();
|
// This allows the application to be hosted behind a reverse proxy with a specific sub-path.
|
||||||
options.KnownNetworks.Clear();
|
if (!string.IsNullOrWhiteSpace(envPath))
|
||||||
|
appBuilder.UsePathBase(new PathString(envPath));
|
||||||
|
|
||||||
if (network == null && address == null)
|
// Configure Forwarded Headers to correctly handle reverse proxy scenarios.
|
||||||
|
var forwardedHeadersOptions = new ForwardedHeadersOptions
|
||||||
{
|
{
|
||||||
// localhost
|
ForwardedHeaders = ForwardedHeaders.All
|
||||||
options.KnownNetworks.Add(new IPNetwork(IPAddress.Loopback, 8));
|
};
|
||||||
options.KnownNetworks.Add(new IPNetwork(IPAddress.IPv6Loopback, 128));
|
|
||||||
|
|
||||||
// private IPv4 networks
|
// Reset KnownProxies and KnownNetworks to avoid default restrictions.
|
||||||
// see https://en.wikipedia.org/wiki/Private_network#Private_IPv4_addresses
|
forwardedHeadersOptions.KnownProxies.Clear();
|
||||||
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("10.0.0.0"), 8));
|
|
||||||
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("172.16.0.0"), 12));
|
|
||||||
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("192.168.0.0"), 16));
|
|
||||||
|
|
||||||
// private IPv6 networks
|
#if NET10_0_OR_GREATER
|
||||||
// see https://en.wikipedia.org/wiki/Private_network#Private_IPv6_addresses
|
forwardedHeadersOptions.KnownIPNetworks.Clear();
|
||||||
options.KnownNetworks.Add(new IPNetwork(IPAddress.Parse("fd00::"), 8));
|
#else
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Clear();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If no specific proxy address or network is provided, use environment variable or defaults.
|
||||||
|
if (proxyAddress == null && proxyNetwork == null)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(envProxy))
|
||||||
|
{
|
||||||
|
#if NET10_0_OR_GREATER
|
||||||
|
// Always trust localhost.
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(IPNetwork.Parse("127.0.0.0/8"));
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(IPNetwork.Parse("::1/128"));
|
||||||
|
|
||||||
|
// Trust common private network ranges.
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(IPNetwork.Parse("10.0.0.0/8"));
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(IPNetwork.Parse("172.16.0.0/12"));
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(IPNetwork.Parse("192.168.0.0/16"));
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(IPNetwork.Parse("fd00::/8"));
|
||||||
|
#else
|
||||||
|
// Always trust localhost.
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(IPNetwork.Parse("127.0.0.0/8"));
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(IPNetwork.Parse("::1/128"));
|
||||||
|
|
||||||
|
// Trust common private network ranges.
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(IPNetwork.Parse("10.0.0.0/8"));
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(IPNetwork.Parse("172.16.0.0/12"));
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(IPNetwork.Parse("192.168.0.0/16"));
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(IPNetwork.Parse("fd00::/8"));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Try to parse proxies from environment variable.
|
||||||
|
string[] envProxies = envProxy.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
|
||||||
|
foreach (string proxy in envProxies)
|
||||||
|
{
|
||||||
|
if (IPAddress.TryParse(proxy, out var address))
|
||||||
|
{
|
||||||
|
forwardedHeadersOptions.KnownProxies.Add(address);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IPNetwork.TryParse(proxy, out var network))
|
||||||
|
{
|
||||||
|
#if NET10_0_OR_GREATER
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(network);
|
||||||
|
#else
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(network);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (network != null)
|
if (proxyAddress != null)
|
||||||
options.KnownNetworks.Add(network);
|
forwardedHeadersOptions.KnownProxies.Add(proxyAddress);
|
||||||
|
|
||||||
if (address != null)
|
#if NET10_0_OR_GREATER
|
||||||
options.KnownProxies.Add(address);
|
if (proxyNetwork.HasValue)
|
||||||
|
forwardedHeadersOptions.KnownIPNetworks.Add(proxyNetwork.Value);
|
||||||
|
#else
|
||||||
|
if (proxyNetwork != null)
|
||||||
|
forwardedHeadersOptions.KnownNetworks.Add(proxyNetwork);
|
||||||
|
#endif
|
||||||
|
|
||||||
app.UseForwardedHeaders(options);
|
appBuilder.UseForwardedHeaders(forwardedHeadersOptions);
|
||||||
|
return appBuilder;
|
||||||
return app;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user