[c#] 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.

This question is related to c# asp.net-core asp.net-core-mvc

The answer is


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 (https://stackoverflow.com/a/41335701/812720) and @David (https://stackoverflow.com/a/8597351/812720), 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


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.


try this.

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

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).


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

You can use the IHttpConnectionFeature for getting this information.

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

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.


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.

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();
    ip = IPAddress.Parse(header);
}
else
{
    // this will always have a value (running locally in development won't have the header)
    ip = Request.HttpContext.Connection.RemoteIpAddress;
}

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();

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();

This works for me (DotNetCore 2.1)

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

In project.json add a dependency to:

"Microsoft.AspNetCore.HttpOverrides": "1.0.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. (https://stackoverflow.com/a/35442401/5326387)


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) https://en.wikipedia.org/wiki/X-Forwarded-For

    // 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.
    // http://stackoverflow.com/a/43554000/538763
    //
    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.


Examples related to c#

How can I convert this one line of ActionScript to C#? Microsoft Advertising SDK doesn't deliverer ads How to use a global array in C#? How to correctly write async method? C# - insert values from file into two arrays Uploading into folder in FTP? Are these methods thread safe? dotnet ef not found in .NET Core 3 HTTP Error 500.30 - ANCM In-Process Start Failure Best way to "push" into C# array

Examples related to asp.net-core

dotnet ef not found in .NET Core 3 How to use Bootstrap 4 in ASP.NET Core ASP.NET Core - Swashbuckle not creating swagger.json file Getting value from appsettings.json in .net core .net Core 2.0 - Package was restored using .NetFramework 4.6.1 instead of target framework .netCore 2.0. The package may not be fully compatible Automatically set appsettings.json for dev and release environments in asp.net core? Get ConnectionString from appsettings.json instead of being hardcoded in .NET Core 2.0 App Unable to create migrations after upgrading to ASP.NET Core 2.0 EF Core add-migration Build Failed ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response

Examples related to asp.net-core-mvc

Getting value from appsettings.json in .net core Unable to create migrations after upgrading to ASP.NET Core 2.0 ASP.NET Core form POST results in a HTTP 415 Unsupported Media Type response ASP.NET Core Get Json Array using IConfiguration ASP.NET Core Dependency Injection error: Unable to resolve service for type while attempting to activate How do I access Configuration in any class in ASP.NET Core? How to register multiple implementations of the same interface in Asp.Net Core? ASP.NET Core Identity - get current user How to get current url in view in asp.net core 1.0 How to return HTTP 500 from ASP.NET Core RC2 Web Api?