How do I get client IP address in ASP.NET Core?

Can you please let me know how to get client IP address in ASP.NET when using MVC 6.Request.ServerVariables["REMOTE_ADDR"] does not work.

1

22 Answers

The API has been updated. Not sure when it changed but according to Damien Edwards in late December, you can now do this:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
11

In project.json add a dependency to:

"Microsoft.AspNetCore.HttpOverrides": "2.2.0"

In Startup.cs, in the Configure() method add:

app.UseForwardedHeaders(new ForwardedHeadersOptions
{ ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
}); 

And, of course:

using Microsoft.AspNetCore.HttpOverrides;

Then, I could get the ip by using:

Request.HttpContext.Connection.RemoteIpAddress

In my case, when debugging in VS I got always IpV6 localhost, but when deployed on an IIS I got always the remote IP.

Some useful links:How do I get client IP address in ASP.NET CORE? and RemoteIpAddress is always null

The ::1 is maybe because of:

Connections termination at IIS, which then forwards to Kestrel, the v.next web server, so connections to the web server are indeed from localhost. ()

Edit 12/2020: Thanks to SolidSnake: as of Dec 2020 the latest version is 2.2.0

Edit 06/2021: Thanks to Hakan Fıstık: In .NET 5 the namespace is Microsoft.AspNetCore.Builder

6

Some fallback logic can be added to handle the presence of a Load Balancer.

Also, through inspection, the X-Forwarded-For header happens to be set anyway even without a Load Balancer (possibly because of additional Kestrel layer?):

public string GetRequestIP(bool tryUseXForwardHeader = true)
{ string ip = null; // todo support new "Forwarded" header (2014) // X-Forwarded-For (csv list): Using the First entry in the list seems to work // for 99% of cases however it has been suggested that a better (although tedious) // approach might be to read each IP from right to left and use the first public IP. // // if (tryUseXForwardHeader) ip = GetHeaderValueAs<string>("X-Forwarded-For").SplitCsv().FirstOrDefault(); // RemoteIpAddress is always null in DNX RC1 Update1 (bug). if (ip.IsNullOrWhitespace() && _httpContextAccessor.HttpContext?.Connection?.RemoteIpAddress != null) ip = _httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(); if (ip.IsNullOrWhitespace()) ip = GetHeaderValueAs<string>("REMOTE_ADDR"); // _httpContextAccessor.HttpContext?.Request?.Host this is the local host. if (ip.IsNullOrWhitespace()) throw new Exception("Unable to determine caller's IP."); return ip;
}
public T GetHeaderValueAs<T>(string headerName)
{ StringValues values; if (_httpContextAccessor.HttpContext?.Request?.Headers?.TryGetValue(headerName, out values) ?? false) { string rawValues = values.ToString(); // writes out as Csv when there are multiple. if (!rawValues.IsNullOrWhitespace()) return (T)Convert.ChangeType(values.ToString(), typeof(T)); } return default(T);
}
public static List<string> SplitCsv(this string csvList, bool nullOrWhitespaceInputReturnsNull = false)
{ if (string.IsNullOrWhiteSpace(csvList)) return nullOrWhitespaceInputReturnsNull ? null : new List<string>(); return csvList .TrimEnd(',') .Split(',') .AsEnumerable<string>() .Select(s => s.Trim()) .ToList();
}
public static bool IsNullOrWhitespace(this string s)
{ return String.IsNullOrWhiteSpace(s);
}

Assumes _httpContextAccessor was provided through DI.

6

You can use the IHttpConnectionFeature for getting this information.

var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;
5

In ASP.NET 2.1, In StartUp.cs Add This Services:

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

and then do 3 step:

  1. Define a variable in your MVC controller

    private IHttpContextAccessor _accessor;
  2. DI into the controller's constructor

    public SomeController(IHttpContextAccessor accessor)
    { _accessor = accessor;
    }
  3. Retrieve the IP Address

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

This is how it is done.

3

I found that, some of you found that the IP address you get is :::1 or 0.0.0.1

This is the problem because of you try to get IP from your own machine, and the confusion of C# that try to return IPv6.

So, I implement the answer from @Johna () and @David (), Thanks to them!

and here to solution:

  1. add Microsoft.AspNetCore.HttpOverrides Package in your References (Dependencies/Packages)

  2. add this line in Startup.cs

    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    { // your current code // start code to add // to get ip address app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto }); // end code to add
    }
  3. to get IPAddress, use this code in any of your Controller.cs

    IPAddress remoteIpAddress = Request.HttpContext.Connection.RemoteIpAddress;
    string result = "";
    if (remoteIpAddress != null)
    { // If we got an IPV6 address, then we need to ask the network for the IPV4 address // This usually only happens when the browser is on the same machine as the server. if (remoteIpAddress.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) { remoteIpAddress = System.Net.Dns.GetHostEntry(remoteIpAddress).AddressList
    .First(x => x.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork); } result = remoteIpAddress.ToString();
    }

and now you can get IPv4 address from remoteIpAddress or result

3
var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
3

This works for me (DotNetCore 2.1)

[HttpGet]
public string Get()
{ var remoteIpAddress = HttpContext.Connection.RemoteIpAddress; return remoteIpAddress.ToString();
}

As of September 2021 - ASP.NET Core (5.x) MVC project allowed me to get the IP Address this way in my controller:

Request.HttpContext.Connection.RemoteIpAddress

Quite a bit more simple now than in the past, it seems.

In my case, I have DotNet Core 2.2 Web App running on DigitalOcean with docker and nginx as reverse proxy. With this code in Startup.cs I can get the client IP

app.UseForwardedHeaders(new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.All, RequireHeaderSymmetry = false, ForwardLimit = null, KnownNetworks = { new IPNetwork(IPAddress.Parse("::ffff:172.17.0.1"), 104) } });

::ffff:172.17.0.1 was the ip that I was getting before using

Request.HttpContext.Connection.RemoteIpAddress.ToString();
0

In .NET 5 I use this to retrieve the client IP via a container on AWS fargate.

public static class HttpContextExtensions
{ // public static IPAddress GetRemoteIPAddress(this HttpContext context, bool allowForwarded = true) { if (allowForwarded) { string header = (context.Request.Headers["CF-Connecting-IP"].FirstOrDefault() ?? context.Request.Headers["X-Forwarded-For"].FirstOrDefault()); if (IPAddress.TryParse(header, out IPAddress ip)) { return ip; } } return context.Connection.RemoteIpAddress; }
}

You call it like this:

var ipFromExtensionMethod = HttpContext.GetRemoteIPAddress().ToString();

Source

Running .NET core (3.1.4) on IIS behind a Load balancer did not work with other suggested solutions.

Manually reading the X-Forwarded-For header does. This code assumes this header contains one IP.

IPAddress ip;
var headers = Request.Headers.ToList();
if (headers.Exists((kvp) => kvp.Key == "X-Forwarded-For"))
{ // when running behind a load balancer you can expect this header var header = headers.First((kvp) => kvp.Key == "X-Forwarded-For").Value.ToString(); // in case the IP contains a port, remove ':' and everything after ip = IPAddress.Parse(header.Remove(header.IndexOf(':')));
}
else
{ // this will always have a value (running locally in development won't have the header) ip = Request.HttpContext.Connection.RemoteIpAddress;
}

Thanks to @JawadAlShaikh and @BozoJoe for pointing out the IP can contain a port and the X-Forwarded-For can contain multiple IPs.

4

First, in .Net Core 1.0 Add using Microsoft.AspNetCore.Http.Features; to the controller Then inside the relevant method:

var ip = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress?.ToString();

I read several other answers which failed to compile because it was using a lowercase httpContext, leading the VS to add using Microsoft.AspNetCore.Http, instead of the appropriate using, or with HttpContext (compiler is also mislead).

Running ASP.NET Core 2.1 behind a Traefik reverse Proxy on Ubuntu, I need to set its gateway IP in KnownProxies after installing the official Microsoft.AspNetCore.HttpOverrides package

 var forwardedOptions = new ForwardedHeadersOptions { ForwardedHeaders = ForwardedHeaders.XForwardedFor, }; forwardedOptions.KnownProxies.Add(IPAddress.Parse("192.168.3.1")); app.UseForwardedHeaders(forwardedOptions);

According to the documentation, this is required if the reverse proxy is not running on localhost. The docker-compose.yml of Traefik has assigned a static IP address:

networks: my-docker-network: ipv4_address: 192.168.3.2

Alternatively, it should be enough to make sure a known network is defined here to specify its gateway in .NET Core.

0

As per the official documentation, if you are using Apache or Nginx integration, following code should be added to the Startup.ConfigureServices method.

// using Microsoft.AspNetCore.HttpOverrides; services.Configure<ForwardedHeadersOptions>(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; // Only loopback proxies are allowed by default. // Clear that restriction because forwarders are enabled by explicit // configuration. options.KnownNetworks.Clear(); options.KnownProxies.Clear(); });

and then on top of everything, in Configure method use

app.UseForwardedHeaders();

Further suppose in nginx conf file, inside a location, use

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;

Now the first entry in the X-Forwarded-For will be the real client IP.

IMPORTANT: If you want to secure the app and not allow an attacker inject X-Forwarded-For, Please read this answer.

Please see Forward the scheme for Linux and non-IIS reverse proxies, Configure Nginx and Dealing with invalid headers

First Add

Microsoft.AspNetCore.Http
services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();

in ConfigureServices in Startup.cs Then Add the following code in your controller

 private IHttpContextAccessor _accessor; public LoginController(IHttpContextAccessor accessor) { _accessor = accessor; } public IEnumerable<string> Get() { var ip = _accessor.HttpContext?.Connection?.RemoteIpAddress?.ToString(); return new string[] { ip, "value" }; }

Hope this will work for you

try this:

string remoteHost = $"{httpContext.Connection.RemoteIpAddress}:{httpContext.Connection.RemotePort}";

1

From this link, there is a better solution.

In Startup.cs, we need to add service-

public void ConfigureServices(IServiceCollection services)
{ ........ services.AddHttpContextAccessor(); ........
}

Then in any controller or any place, we need to use it via dependency injection like this-

private IHttpContextAccessor HttpContextAccessor { get; }
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options, IWebHostEnvironment env, IHttpContextAccessor httpContextAccessor) : base(options)
{ Environment = env; HttpContextAccessor = httpContextAccessor; //this.Database.EnsureCreated();
}

And then get IP like this-

IPAddress userIp = HttpContextAccessor.HttpContext.Connection.RemoteIpAddress;

Short version of @crokusek's answer

public string GetUserIP(HttpRequest req)
{ var ip = req.Headers["X-Forwarded-For"].FirstOrDefault(); if (!string.IsNullOrWhiteSpace(ip)) ip = ip.Split(',')[0]; if (string.IsNullOrWhiteSpace(ip)) ip = Convert.ToString(req.HttpContext.Connection.RemoteIpAddress); if (string.IsNullOrWhiteSpace(ip)) ip = req.Headers["REMOTE_ADDR"].FirstOrDefault(); return ip;
}
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
public string GetClientIPAddress(HttpContext context) { string ip = string.Empty;
if (!string.IsNullOrEmpty(context.Request.Headers["X-Forwarded-For"])) { ip = context.Request.Headers["X-Forwarded-For"]; } else { ip = context.Request.HttpContext.Features.Get<IHttpConnectionFeature>().RemoteIpAddress.ToString(); } return ip; }

Where you want to get Ip address;

GetClientIPAddress(HttpContext);

try this.

var host = Dns.GetHostEntry(Dns.GetHostName()); foreach (var ip in host.AddressList) { if (ip.AddressFamily == AddressFamily.InterNetwork) { ipAddress = ip.ToString(); } }
1

To get IP address and hostname in .NET Core, put the following code in the controller:

var addlist = Dns.GetHostEntry(Dns.GetHostName());
string GetHostName = addlist.HostName.ToString();
string GetIPV6 = addlist.AddressList[0].ToString();
string GetIPV4 = addlist.AddressList[1].ToString();
3

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like