C# 在ASP.NET核心中,如何检查请求是否为本地请求?

C# 在ASP.NET核心中,如何检查请求是否为本地请求?,c#,asp.net-core,C#,Asp.net Core,在常规ASP.NET中,您可以在视图中执行此操作,以确定当前请求是否来自本地主机: HttpContext.Current.Request.IsLocal 但是我在ASP.NET 6/Core/中找不到类似的东西,不管它是什么名字。现在 HttpContext.Connection.IsLocal 如果需要在控制器外部检查,则需要依赖于IHttpContextAccessor来访问它 根据评论更新: HttpContext在视图中本质上是可用的 @if (Context.Connection.

在常规ASP.NET中,您可以在视图中执行此操作,以确定当前请求是否来自本地主机:

HttpContext.Current.Request.IsLocal

但是我在ASP.NET 6/Core/中找不到类似的东西,不管它是什么名字。

现在

HttpContext.Connection.IsLocal
如果需要在控制器外部检查,则需要依赖于
IHttpContextAccessor
来访问它

根据评论更新:

HttpContext
在视图中本质上是可用的

@if (Context.Connection.IsLocal)
{

}

更新:ASP.NET Core 2.0有一个名为
Url.IsLocalUrl
的方法(请参见此)

我认为这段代码可以工作,但我还不能完全测试它

var callingUrl = Request.Headers["Referer"].ToString();
var isLocal = Url.IsLocalUrl(callingUrl);
但请参见下文迪安对该方法的评论:


任何想使用“更新”版本检查referer头的人都应该记住,头极易被欺骗,其程度不适用于环回IP地址


原始解决方案

我遇到这个问题是为了找到一个解决方案,知道一个请求是否是本地的。不幸的是,ASP.NET 1.1.0版在连接上没有
IsLocal
方法。我在一个名为的网站上找到了一个解决方案,但它也过时了

我已经创建了自己的
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;
    }
}
您可以使用
请求
属性在控制器操作中调用它,即

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

我希望这对某人有所帮助。

在编写HttpContext.Connection.IsLocal时,.NETCore中现在缺少了

其他工作解决方案仅检查第一个环回地址(
::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());

我还要提到的是,在自定义
IsLocal()
检查的末尾添加以下子句可能会很有用

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

这可以解释这样一种情况,即使用Microsoft.AspNetCore.TestHost运行站点,并且站点完全在内存中本地运行,而没有实际的TCP/IP连接。

以上这些都不适用于我

工作原理非常不同,我发现它有点无用:

例如,以下URL被视为本地URL:

  /Views/Default/Index.html
  ~/Index.html
以下URL为非本地URL:

  ../Index.html
  http://www.contoso.com/
  http://localhost/Index.html
HttpContext.Connection.IsLocal
在.Net Core 2.2中不存在

比较
ControllerContext.HttpContext.Connection.RemoteIpAddress
ControllerContext.HttpContext.Connection.LocalIpAddress
在我的测试中也不起作用,因为我得到了:1“表示远程ip,127.0.0.1”表示本地ip

最后,我使用了这一块:

IPAddress addr = System.Net.IPAddress.Parse( HttpContext.Connection.RemoteIpAddress.ToString() );
if (System.Net.IPAddress.IsLoopback(addr) )
{
    //do something
}

派对迟到了,但如果我想在.Net core 2.2+中检查razor视图中的IsLocal,我只需执行以下操作:

@if (Context.Request.Host.Value.StartsWith("localhost"))
{
    //do local stuff
}
ASP.NET Core 3.1的更新 您可以使用以下选项:

if (Request.Host.Host == "localhost") {// do something }

小心使用
HttpContext.Connection.IsLocal
。在我看来,使用
HttpContext.Connection.RemoteIpAddress
更安全。如果我在本地连接到测试ASP.NET 5 RC1项目,我会在
RemoteIpAddress
中看到
:1
,但是
HttpContext.Connection.IsLocal
false
。这是错误的。干杯,奥列格,你说的对我来说也是真的。我也有同样的行为。在本地总是
false
,我通过执行
@injectIHTTPContextAccessor上下文在视图中获取依赖项对吗?“当前为本地”始终为false…这将在RC2中消失。Filip在这里有另一种方法:但即使它似乎也严重依赖于其他中间件和您使用的服务器。这对我很有帮助。是我的版本。任何想使用检查Referer标头的“更新”版本的人都应该记住,标头极易被欺骗,其程度不适用于环回IP地址。此方法可以简化为
public static bool IsLocalRequest(HttpContext上下文)=>context.Connection.RemoteIpAddress.Equals(context.Connection.LocalIpAddress)| | IPAddress.IsLoopback(context.Connection.RemoteIpAddress)
第二个
if
不应该读
if(IPAddress.IsLoopback(context.Connection.LocalIpAddress))
而不是使用
remoteipAddress
?我认为这在实践中没有什么区别,如果有人通过环回或其他方式创建到外部接口地址的连接,则函数可能返回false,但默认情况下不会发生这种情况,因此无论是远程检查还是本地检查,都将拾取127范围或IPv6中的任何IP地址。此外,由于检查是关于到服务器的远程连接,因此检查远程地址更符合目的。这是一种非常丑陋的方法。如果您有一个名为localhost.site.com的站点怎么办?甚至localhosting.com。