Raghunath Machineni
Raghunath Machineni

Reputation: 43

Issue with getting Real Client IP Address when load balancer is in place

I am not able to get real client IP address using X-Forwarded-For header. My application is built on Dot net core 1.1 not 3.0 which is latest. And we have load balancer set up to distribute the load.

And I have implemented code as mentioned in below MSDN article.

https://learn.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-3.0&viewFallbackFrom=aspnetcore-1.1#forwarded-headers-middleware-options 

this is article used for implementation

sample code

1) Configure services with forward options

  public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.
            services.AddApplicationInsightsTelemetry(Configuration);
            services.Configure<AppSettings>(Configuration);
            services.AddMvc();
            services.Configure<ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders =
                    ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
                options.ForwardLimit = 2;
                options.KnownProxies.Add(System.Net.IPAddress.Parse("123.111.11.88"));
                //options.KnownProxies.Clear();
                //options.KnownNetworks.Clear();
            });
        }

here 123.111.11.88 is sample Load balancer IP address.

2) Configure method changes as below:

  public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
           --------
            app.UseForwardedHeaders();
           -------
      }

3) Code to read headers as below:

 string realClientIP = GetHeaderValueAs<string>("X-Cluster-Client-Ip");

 public T GetHeaderValueAs<T>(string headerName)
        {
            StringValues values;

            Request.Headers.TryGetValue(headerName, out values);
            if (!StringValues.IsNullOrEmpty(values))
            {
                var rawValues = values.ToString();

                if (!string.IsNullOrEmpty(rawValues))
                    return (T)Convert.ChangeType(values.ToString(), typeof(T));
            }

            return default(T);
        }

queries:

1) is this right way to get real client IP with dot net core 1.1 since I could see that MSDN article is for dot net core 3.0 and there is no reference article for core 1.0.

2) Is it possible to get result using custom headers and how it can be done if possible ?

3) Please let me know if there is any other way ?

Upvotes: 1

Views: 1518

Answers (1)

Alex Nguyen
Alex Nguyen

Reputation: 1080

Step 1. Change your code to

 services.Configure<ForwardedHeadersOptions>(options =>
        {
            options.ForwardedHeaders =
                ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto;
  
              options.KnownProxies.Clear();
             options.KnownNetworks.Clear();
        });

Step 2. add ContextAccessor

 services.AddHttpContextAccessor();
        services.TryAddSingleton<IActionContextAccessor, ActionContextAccessor>();

Step 3. Use IActionContextAccessor to get the IP like the below method

public static string GetClientIp(this IActionContextAccessor contextAccessor)
    {
        var remoteIp = contextAccessor.ActionContext.HttpContext.Connection.RemoteIpAddress;

        if (remoteIp.IsIPv4MappedToIPv6)
        {
            remoteIp = remoteIp.MapToIPv4();
        }

        return remoteIp.ToString();
    }

Upvotes: 2

Related Questions