patterncsharpMinor
Get host ip address behind load balancer or without lb
Viewed 0 times
withoutaddressgethostloadbalancerbehind
Problem
Description
Aplication type: WEB API
.NET Framework: 4.5
MVC: 5
I need caller host ip in my custom action filter and then in action. On some enviroments we have configured load balancer which stores caller ip in header "HTTP_X_FORWARDED_FOR". I nedd my code works with LB or without.
CODE
Filter
Controller
Filter registration:
```
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using FAPTest.TestApp.ActionFilters;
namespace FAPTest.TestApp
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.Regi
Aplication type: WEB API
.NET Framework: 4.5
MVC: 5
I need caller host ip in my custom action filter and then in action. On some enviroments we have configured load balancer which stores caller ip in header "HTTP_X_FORWARDED_FOR". I nedd my code works with LB or without.
CODE
Filter
using System.Collections.Generic;
using System.Web;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
namespace FAPTest.TestApp.ActionFilters
{
public class AccessControlFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
string ip = HttpContext.Current.Request.UserHostAddress;
string sourceIp = HttpContext.Current.Request.ServerVariables.Get("HTTP_X_FORWARDED_FOR");
string ipAddress = ip;
if (!string.IsNullOrEmpty(sourceIp))
{
ipAddress = sourceIp;
}
actionContext.Request.Properties.Add(new KeyValuePair("ipAddress", ipAddress));
}
}
}Controller
using System.Web.Http;
namespace FAPTest.TestApp.Controllers
{
public class TestController : ApiController
{
[HttpGet]
public string Test()
{
object o = null;
string ipAddress = null;
if (Request.Properties.TryGetValue("ipAddress", out o))
{
ipAddress = (string)o;
}
return ipAddress;
}
}
}Filter registration:
```
using System.Web.Http;
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using FAPTest.TestApp.ActionFilters;
namespace FAPTest.TestApp
{
public class WebApiApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
GlobalConfiguration.Configure(WebApiConfig.Register);
FilterConfig.Regi
Solution
Here is a pattern I've used successfully. However, you need to be aware that the X-FORWARDED-FOR header may contain a comma separated list of ip addresses. This solution also helps with protocol sniffing, because most secure sites will need to force the web browser to SSL, and if you are using SSL OFFLOADING, you'll need to use the x-forwarded-proto header to determine if a redirect is required.
Example format of header value:
See https://en.wikipedia.org/wiki/X-Forwarded-For
string ipAddress = string.Empty;
string protocol = string.Empty;
string port = string.Empty;
if (Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-For") != null)
{
protocol = (Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-Proto")).FirstOrDefault();
ipAddress = (Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-For")).FirstOrDefault();
port = Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-Port").FirstOrDefault();
}
if (string.IsNullOrWhiteSpace(protocol))
{
protocol = (this.Request.IsSecureConnection ? "HTTPS" : "HTTP");
ipAddress = this.Request.UserHostAddress;
}Example format of header value:
X-Forwarded-For: client, proxy1, proxy2See https://en.wikipedia.org/wiki/X-Forwarded-For
Code Snippets
string ipAddress = string.Empty;
string protocol = string.Empty;
string port = string.Empty;
if (Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-For") != null)
{
protocol = (Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-Proto")).FirstOrDefault();
ipAddress = (Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-For")).FirstOrDefault();
port = Request.RequestContext.HttpContext.Request.Headers.GetValues("X-Forwarded-Port").FirstOrDefault();
}
if (string.IsNullOrWhiteSpace(protocol))
{
protocol = (this.Request.IsSecureConnection ? "HTTPS" : "HTTP");
ipAddress = this.Request.UserHostAddress;
}X-Forwarded-For: client, proxy1, proxy2Context
StackExchange Code Review Q#136068, answer score: 3
Revisions (0)
No revisions yet.