/// <summary> /// Forwards proxied headers onto current request /// </summary> /// <param name="builder"></param> /// <param name="options">Enables the different forwarding options.</param> /// <returns></returns> public static IApplicationBuilder UseForwardedHeaders(this IApplicationBuilder builder, ForwardedHeadersOptions options) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return builder.UseMiddleware<ForwardedHeadersMiddleware>(Options.Create(options)); }
public ForwardedHeadersMiddleware(RequestDelegate next, ILoggerFactory loggerFactory, IOptions<ForwardedHeadersOptions> options) { if (next == null) { throw new ArgumentNullException(nameof(next)); } if (loggerFactory == null) { throw new ArgumentNullException(nameof(loggerFactory)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } _options = options.Value; _logger = loggerFactory.CreateLogger<ForwardedHeadersMiddleware>(); _next = next; }
public async Task XForwardedForForwardLimit(int limit, string header, string expectedIp, int expectedPort, string remainingHeader) { var assertsExecuted = false; var builder = new WebHostBuilder() .Configure(app => { app.Use((context, next) => { context.Connection.RemoteIpAddress = IPAddress.Parse("10.0.0.1"); context.Connection.RemotePort = 99; return next(); }); var options = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor, ForwardLimit = limit, }; options.KnownProxies.Clear(); options.KnownNetworks.Clear(); app.UseForwardedHeaders(options); app.Run(context => { Assert.Equal(expectedIp, context.Connection.RemoteIpAddress.ToString()); Assert.Equal(expectedPort, context.Connection.RemotePort); Assert.Equal(remainingHeader, context.Request.Headers["X-Forwarded-For"].ToString()); assertsExecuted = true; return Task.FromResult(0); }); }); var server = new TestServer(builder); var req = new HttpRequestMessage(HttpMethod.Get, ""); req.Headers.TryAddWithoutValidation("X-Forwarded-For", header); await server.CreateClient().SendAsync(req); Assert.True(assertsExecuted); }
public void AllForwardsDisabledByDefault() { var options = new ForwardedHeadersOptions(); Assert.True(options.ForwardedHeaders == ForwardedHeaders.None); Assert.Equal(1, options.ForwardLimit); Assert.Equal(1, options.KnownNetworks.Count()); Assert.Equal(1, options.KnownProxies.Count()); }
public async Task XForwardedProtoOverrideLimitedByLoopback(string protoHeader, string forHeader, string remoteIp, bool loopback, string expected) { var assertsExecuted = false; var builder = new WebHostBuilder() .Configure(app => { app.Use((context, next) => { context.Connection.RemoteIpAddress = IPAddress.Parse(remoteIp); return next(); }); var options = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedProto | ForwardedHeaders.XForwardedFor, ForwardLimit = 5, }; if (!loopback) { options.KnownNetworks.Clear(); options.KnownProxies.Clear(); } app.UseForwardedHeaders(options); app.Run(context => { Assert.Equal(expected, context.Request.Scheme); assertsExecuted = true; return Task.FromResult(0); }); }); var server = new TestServer(builder); var req = new HttpRequestMessage(HttpMethod.Get, ""); req.Headers.Add("X-Forwarded-Proto", protoHeader); req.Headers.Add("X-Forwarded-For", forHeader); await server.CreateClient().SendAsync(req); Assert.True(assertsExecuted); }
/// <summary> /// Applies forwarded headers to their matching fields on the current request. /// <para> /// By convention, HTTP proxies forward information from the client in well-known HTTP headers. /// The <see cref="ForwardedHeadersMiddleware"/> reads these headers and fills in the associated fields on HttpContext. /// </para> /// </summary> /// <param name="builder">The <see cref="IApplicationBuilder" />.</param> /// <param name="options">Enables the different forwarding options.</param> /// <returns>A reference to <paramref name="builder" /> after the operation has completed.</returns> public static IApplicationBuilder UseForwardedHeaders(this IApplicationBuilder builder, ForwardedHeadersOptions options) { if (builder == null) { throw new ArgumentNullException(nameof(builder)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return(builder.UseMiddleware <ForwardedHeadersMiddleware>(Options.Create(options))); }