HttpContext.Connection.RemoteIpAddress и LocalIpAddress, LocalPort имеет значение null в net core 2.1 [duplicate]

В Java, когда оператор «==» используется для сравнения двух объектов, он проверяет, ссылаются ли объекты на одно и то же место в памяти. Другими словами, он проверяет, являются ли имена двух объектов в основном ссылками на одно и то же место в памяти.

Класс Java String фактически переопределяет реализацию equals () по умолчанию в классе Object и переопределяет этот метод, чтобы он проверял только значения строк, а не их местоположения в памяти. Это означает, что если вы вызываете метод equals () для сравнения двух объектов String, то, пока действительная последовательность символов равна, оба объекта считаются равными.

Оператор == проверяет, являются ли две строки точно одним и тем же объектом.

Метод .equals() проверяет, имеют ли две строки одно и то же значение.

101
задан Vadim Ovchinnikov 10 December 2017 в 06:36
поделиться

6 ответов

API обновлен. Не уверен, когда он изменился, но в соответствии с Дамиеном Эдвардсом в конце декабря вы можете сделать это:

var remoteIpAddress = request.HttpContext.Connection.RemoteIpAddress;
131
ответ дан David Peden 15 August 2018 в 15:32
поделиться
  • 1
    RemoteIpAddress всегда null для меня, когда я публикую его сайт в IIS и записываю его в файл. – A-Sharabiani 16 February 2016 в 19:52
  • 2
    Похоже, проблема была исправлена ​​в rc 2 – Jon 5 October 2016 в 15:26
  • 3
    System.Net.IPAddress remoteIpAddress = this.Request.HttpContext.Connection.RemoteIpAddress; – Stefan Steiger 13 October 2016 в 04:41
  • 4
    Я всегда получаю 127.0.0.1, даже когда я подключаюсь удаленно – frostymarvelous 21 October 2016 в 15:01
  • 5
    Это возвращает & quot; :: 1 & quot; для меня это формат IPv6. Как другие видят 127.0.0.1? – Derek Greer 28 October 2016 в 15:36
var remoteIpAddress = HttpContext.Features.Get<IHttpConnectionFeature>()?.RemoteIpAddress;
11
ответ дан feradz 15 August 2018 в 15:32
поделиться
  • 1
    Слишком сложно. MVC уже вызывает это внутри и помещает его под HttpContext.Connection.RemoteIpAddress. – Fred 22 April 2016 в 12:28
  • 2
    @Fred - ваша версия возвращает null для меня в RC-1 - IIS и Kestrel – fiat 3 May 2016 в 00:15

Некоторая резервная логика может быть добавлена ​​для управления наличием балансировки нагрузки.

Кроме того, при проверке заголовок 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.

41
ответ дан Greg0 15 August 2018 в 15:32
поделиться
  • 1
    Это правильный ответ. Существует не один способ получить IP-адрес, особенно когда ваше приложение находится за Nginx, балансировщик нагрузки или что-то в этом роде. Благодаря! – Feu 2 October 2016 в 02:54
  • 2
    @feu, поскольку AspNetCore может переопределить свойство RemoteIpAddress с заголовками, такими как X-Forwarded-For. – Mark Lopez 15 February 2018 в 23:59
  • 3
    @crokusek ... пытается адаптировать ваше решение, но VS вынуждает меня к классу, инкапсулирующему этот код статическим. У вас есть этот код в проекте веб-приложения или в библиотеке классов в решении? – dinotom 5 April 2018 в 17:07
  • 4
    Первые 2 метода должны быть в экземпляре, который предоставляет __httpContextAccessor (или адаптирует его). Второй метод из двух строк был извлечен из отдельного класса статических расширений. – crokusek 5 April 2018 в 17:22

Сначала в .Net Core 1.0 Добавить using Microsoft.AspNetCore.Http.Features; в контроллер Затем внутри соответствующего метода:

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

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

1
ответ дан Guy 15 August 2018 в 15:32
поделиться

В 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, но при развертывании в IIS Я всегда получал удаленный IP-адрес.

Некоторые полезные ссылки: Как получить IP-адрес клиента в ASP.NET CORE? и RemoteIpAddress всегда null

Возможно, это ::1 из-за:

Прекращение соединений в IIS, которое затем пересылается в Kestrel, веб-сервер v.next, поэтому подключения к веб-серверу действительно от локального хоста. ( https://stackoverflow.com/a/35442401/5326387 )

33
ответ дан jgauffin 15 August 2018 в 15:32
поделиться
  • 1
    Это правильный ответ, который также задокументирован в официальной документации по обратным прокси: docs.microsoft.com/en-us/aspnet/core/host-and-deploy/… – Yaurthek 27 February 2018 в 21:38
  • 2
    необходимо указать, что «app.UseForwardedHeaders ...» необходимо добавить до app.UseAuthentication (); line, если вы используете indentity – netfed 6 April 2018 в 01:09
  • 3
    Это сработало отлично, и я тестировал локально IIS и на Azure. Работает в обоих местах. – Thomas Clemensen 27 April 2018 в 11:30

Вы можете использовать IHttpConnectionFeature для получения этой информации.

var remoteIpAddress = httpContext.GetFeature<IHttpConnectionFeature>()?.RemoteIpAddress;
16
ответ дан Kiran Challa 15 August 2018 в 15:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: