Як отримати IP-адресу клієнта в ASP.NET CORE?


206

Чи можете ви, будь ласка, повідомте мене, як отримати IP-адресу клієнта в ASP.NET при використанні MVC 6. Request.ServerVariables["REMOTE_ADDR"]не працює.


Приклад:httpContext.GetFeature<IHttpConnectionFeature>().RemoteIpAddress
Кіран Чалла

Причина затримки доступна внизу питання: "Занадто багато можливих відповідей, або хороших відповідей буде занадто довго для цього формату. Будь ласка, додайте деталі, щоб звузити набір відповідей або виділити питання, на яке можна відповісти в кілька абзаців ".
Кевін Браун

12
Я не думаю, що відповідь досить довгий. Це звичайна річ, яку ми робимо в старих версіях MVC. Я просто запитав, як це зробити в останній бета-версії. По-друге, якщо відповідей багато, чому б ніхто не вказав мене на ОДНЕ з них. Infact, MVC 6 є бета-версією, і я думаю, що вони навіть не прочитали належним чином питання, перш ніж проводити його.
eadam

Відредагуйте своє запитання, показуючи більше того, що ви спробували, та чіткий ввід / вихід. не нарікайте лише на те, що ваше питання було закрито, хоча б не намагалися його покращити.

10
Тільки програмісти з одного домену мають закрити це питання. Кожен, хто працює в asp.net 5.0, просто дізнається, про що я прошу в частку секунди. Решта ви просто караєте мене за те, що я розмістив просто просте запитання.
eadam

Відповіді:


276

API оновлено. Не впевнений, коли він змінився, але, за словами Деміена Едвардса в кінці грудня, тепер ви можете це зробити:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;

9
Це RemoteIpAddressзавжди nullдля мене, коли я публікую його веб-сайт на IIS і записую це у файл.
А-Шарабіані

3
Схоже , що проблема була вирішена в гс 2
Джон

12
Я завжди отримую 127.0.0.1, навіть коли підключаюсь віддалено
frostymarvelous

33
Для мене це повернення ":: 1", що є формою IPv6. Як інші бачать 127.0.0.1?
Дерек Грір

4
Хтось ще повертає локальну IP-адресу свого IIS-сервера?
dave317

73

У project.json додайте залежність до:

"Microsoft.AspNetCore.HttpOverrides": "1.0.0"

В Startup.cs, у Configure()методі додайте:

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

І звичайно:

using Microsoft.AspNetCore.HttpOverrides;

Тоді я міг отримати ip, використовуючи:

Request.HttpContext.Connection.RemoteIpAddress

У моєму випадку під час налагодження у VS я завжди отримував IpV6 localhost, але при розгортанні на IIS я завжди отримував віддалений IP.

Деякі корисні посилання: Як отримати IP-адресу клієнта в ASP.NET CORE? і RemoteIpAddress завжди є нульовим

Можливо, ::1це через:

Припинення з'єднань на IIS, яке потім пересилає до Kestrel, веб-сервера v.next, тому з'єднання з веб-сервером справді є з localhost. ( https://stackoverflow.com/a/35442401/5326387 )


6
Це правильна відповідь, який також задокументований на офіційну документації про зворотні проксі - серверах: docs.microsoft.com/en-us/aspnet/core/host-and-deploy / ...
Мелвін

8
потрібно зазначити, що "app.UseForwardedHeaders ..." потрібно додати перед app.UseAuthentication (); рядок, якщо ви використовуєте
відступ

1
Це спрацювало чудово, і я перевірив, що на локальних IIS та на Azure. Працює обидва місця.
ThomasCle

72

Можна додати деяку резервну логіку для обробки наявності балансира навантаження.

Крім того, за допомогою інспекції, X-Forwarded-Forзаголовок все-таки встановлюється навіть без балансира завантаження (можливо, через додатковий шар Kestrel?):

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

Припускає, що _httpContextAccessorбуло надано через DI.


2
ЦЕ правильна відповідь. Існує не єдиний спосіб отримати IP-адресу, особливо коли ваша програма стоїть за Nginx, балансиром навантаження або чимось подібним. Дякую!
Feu

@feu, оскільки AspNetCore може замінити властивість RemoteIpAddress із заголовками на зразок X-Forwarded-For.
Марк Лопес

@crokusek ... намагаюся адаптувати своє рішення, але VS змушує мене до класу, що інкапсулює цей код статичним. У вас є цей код у вашому проекті веб-додатків або в бібліотеці класів у рішенні?
динотом

Перші два методи повинні бути в екземплярі, який забезпечує __httpContextAccessor (або адаптувати його). Другі 2 рядкові методи були виведені з окремого класу статичних розширень.
крокусек

Це хороше рішення, особливо коли ваш додаток використовує Kestrel і розміщений з Nginx в Linux.
Тимофій

16

Ви можете використати IHttpConnectionFeatureдля отримання цієї інформації.

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

Дякую за відповідь!
eadam

2
Чи працює це для хостингу Kestrel? У моїй демонстрації httpContext.GetFeature<IHttpConnectionFeature>()завжди будь null.
Джеррі Біан

2
@JerryBian відповідно до цього документа: github.com/aspnet/Docs/blob/master/aspnet/fundamentals/… , IHttpConnectionFeature не підтримується в Kestrel (поки що).
qbik

@JerryBian це зараз
Девід Педен

Повинен бути застарілим - версія @feradz працює для мене в RC-1
фіат

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

6
Надмірно складний. MVC вже називає це внутрішньо і ставить його під HttpContext.Connection.RemoteIpAddress.
Фред

@Fred - ваша версія повертає нульові показники для мене в RC-1 - IIS та Kestrel
fiat

7

Це працює для мене (DotNetCore 2.1)

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

7

В ASP.NET 2.1, в StartUp.cs Додайте ці послуги:

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

а потім зробіть 3 кроки:

  1. Визначте змінну у контролері MVC

    private IHttpContextAccessor _accessor;
  2. DI в конструктор контролера

    public SomeController(IHttpContextAccessor accessor)
    {
        _accessor = accessor;
    }
  3. Отримайте IP-адресу

    _accessor.HttpContext.Connection.RemoteIpAddress.ToString()

Ось як це робиться.


2
Це дає мені: 1. Asp.Net Core 2.2., На localhost.
Stian

::1є localhost в IPv6. Еквівалент IPv4127.0.0.1
Енді

3

У моєму випадку у мене є веб-додаток DotNet Core 2.2, що працює на DigitalOcean з docker і nginx як зворотний проксі. За допомогою цього коду в Startup.cs я можу отримати клієнтський 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 був ip, який я отримував перед використанням

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

2

Спочатку в .Net Core 1.0 Додати using Microsoft.AspNetCore.Http.Features;до контролера. Потім всередині відповідного методу:

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

Я прочитав кілька інших відповідей, які не вдалося зібрати, оскільки він використовував малий регістр httpContext, що призводить VS до додавання за допомогою Microsoft.AspNetCore.Http замість відповідного використання або з HttpContext (компілятор також вводить в оману).


2

отримати ipaddress та ім'я хоста в ядрі .net

поставити цей код у контролер

Виконайте ці кроки:

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

2

Я виявив, що деякі з вас виявили, що отримана вами IP-адреса ::: 1 або 0.0.0.1

Ця проблема полягає в тому, що ви намагаєтеся отримати IP від ​​власної машини і плутанину C #, які намагаються повернути IPv6.

Отже, я реалізую відповідь від @Johna ( https://stackoverflow.com/a/41335701/812720 ) та @David ( https://stackoverflow.com/a/8597351/812720 ), дякую їм!

і тут для вирішення:

  1. додайте пакет Microsoft.AspNetCore.HttpOverrides у свої посилання (залежності / пакети)

  2. додайте цей рядок у 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. щоб отримати IPAddress, використовуйте цей код у будь-якому вашому 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();
    }

і тепер ви можете отримати IPv4 адресу від remoteIpAddress або результат


1

спробуйте це.

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

0

Запуск .NET core(3.1.4) IISпозаду балансира навантаження не працював з іншими запропонованими рішеннями.

Ручне читання X-Forwarded-Forзаголовка робить.

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;
}

Я запускаю автономний пакет, використовуючи хостинг-пакет .


0

Запуск ASP.NET Core 2.1 за Traefik зворотним проксі на Ubuntu, мені потрібно встановити його IP-шлюз KnownProxiesпісля встановлення офіційного Microsoft.AspNetCore.HttpOverridesпакета

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

Згідно з документацією , це потрібно, якщо зворотний проксі не працює на localhost. docker-compose.ymlЗ Traefik призначив статичний IP - адреса:

networks:
  my-docker-network:
    ipv4_address: 192.168.3.2

В якості альтернативи, цього має бути достатньо, щоб переконатися, що відома мережа визначена тут, щоб вказати її шлюз у .NET Core.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.