В ASP.NET Core, как вы проверяете, является ли запрос локальным?

В обычном ASP.NET вы можете сделать это, чтобы определить, был ли текущий запрос от localhost:

HttpContext.Current.Request.IsLocal

Но я не могу найти что-то похожее в ASP.NET 6/Core/как бы оно ни называлось.

Ответ 1

ОБНОВЛЕНИЕ: ASP.NET Core 2.0 имеет метод под названием Url.IsLocalUrl (см. Этот документ Microsoft).

Я думаю, что этот код будет работать, но я не смог протестировать его полностью

var callingUrl = Request.Headers["Referer"].ToString();
var isLocal = Url.IsLocalUrl(callingUrl);

Но см. Комментарий Дина Уилла ниже об этом подходе:

Любой, кто задумывается об использовании "обновленной" версии, которая проверяет заголовок Referrer, должен иметь в виду, что заголовки чрезвычайно легко подделать, до такой степени, что это не относится к петлевым IP-адресам.


Оригинальное решение

Я наткнулся на это в поисках решения, чтобы узнать, является ли запрос локальным. К сожалению, ASP.NET версии 1.1.0 не имеет метода IsLocal для соединения. Я нашел одно решение на веб-сайте Strathweb, но оно тоже устарело.

Я создал свое собственное расширение IsLocal, и оно, кажется, работает, но я не могу сказать, что я проверял его при любых обстоятельствах, но вы можете попробовать его.

public static class IsLocalExtension
{
    private const string NullIpAddress = "::1";

    public static bool IsLocal(this HttpRequest req)
    {
        var connection = req.HttpContext.Connection;
        if (connection.RemoteIpAddress.IsSet())
        {
            //We have a remote address set up
            return connection.LocalIpAddress.IsSet() 
                  //Is local is same as remote, then we are local
                ? connection.RemoteIpAddress.Equals(connection.LocalIpAddress) 
                  //else we are remote if the remote IP address is not a loopback address
                : IPAddress.IsLoopback(connection.RemoteIpAddress);
        }

        return true;
    }

    private static bool IsSet(this IPAddress address)
    {
        return address != null && address.ToString() != NullIpAddress;
    }
}

Вы вызываете это в действии контроллера, используя свойство Request, т.е.

 public IActionResult YourAction()
 {
     var isLocal = Request.IsLocal();
     //... your code here
 }

Я надеюсь, что это помогает кому-то.

Ответ 2

На момент написания HttpContext.Connection.IsLocal теперь отсутствует в .NET Core.

Другое рабочее решение проверяет только первый адрес обратной связи (::1 или 127.0.0.1), который может быть недостаточным.

Я считаю решение ниже полезным:

using Microsoft.AspNetCore.Http;
using System.Net;

namespace ApiHelpers.Filters
{
    public static class HttpContextFilters
    {
        public static bool IsLocalRequest(HttpContext context)
        {
            if (context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress))
            {
                return true;
            }
            if (IPAddress.IsLoopback(context.Connection.RemoteIpAddress))
            {
                return true;
            }
            return false;
        }
    }
}

И пример использования:

app.UseWhen(HttpContextFilters.IsLocalRequest, configuration => configuration.UseElmPage());

Ответ 3

теперь это

HttpContext.Connection.IsLocal

и если вам нужно проверить это за пределами контроллера, вы получите зависимость от IHttpContextAccessor для получения доступа к нему.

Обновление на основе комментария:

HttpContext изначально доступен в представлениях

@if (Context.Connection.IsLocal)
{

}

Ответ 4

Я бы также упомянул, что может быть полезно добавить предложение ниже в конец вашей пользовательской IsLocal() check

if (connection.RemoteIpAddress == null && connection.LocalIpAddress == null)
{
    return true;
}

Это будет учитывать сценарий, в котором выполняется сайт, используя Microsoft.AspNetCore.TestHost, и сайт выполняется полностью локально в памяти без фактического соединения TCP/IP.