簡體   English   中英

在 ASP.NET Core 中,如何檢查請求是否是本地的?

[英]In ASP.NET Core how do you check if request is local?

在常規 ASP.NET 中,您可以在視圖中執行此操作以確定當前請求是否來自 localhost:

HttpContext.Current.Request.IsLocal

但是我在 ASP.NET 6/Core/無論它要被調用的東西中都找不到類似的東西。

更新:ASP.NET Core 2.0 有一個名為Url.IsLocalUrl的方法(請參閱此Microsoft Docs )。

認為這段代碼會起作用,但我還沒有能夠完全測試它

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

但請參閱下面 Will Dean 對這種方法的評論:

任何考慮使用檢查 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
 }

我希望能幫助某人。

在撰寫本文時,.NET Core 中現在缺少HttpContext.Connection.IsLocal

其他工作解決方案僅檢查第一個環回地址( ::1127.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());

以上都不適合我。

Url.IsLocalUrl 的工作方式非常不同,我覺得它有點沒用:

例如,以下 URL 被視為本地 URL:

  /Views/Default/Index.html
  ~/Index.html

以下 URL 是非本地的:

  ../Index.html
  http://www.contoso.com/
  http://localhost/Index.html

.Net Core 2.2 中不存在HttpContext.Connection.IsLocal

比較ControllerContext.HttpContext.Connection.RemoteIpAddressControllerContext.HttpContext.Connection.LocalIpAddress在我的測試中也不起作用,因為我得到了遠程 ip 的“::1”和本地 ip 的“127.0.0.1”。

最后,我用了這一段:

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

遲到了,但是如果我想在 .Net core 2.2+ 的剃刀視圖中檢查 IsLocal,我就這樣做:

@if (Context.Request.Host.Value.StartsWith("localhost"))
{
    //do local stuff
}

現在它的

HttpContext.Connection.IsLocal

如果您需要在控制器之外檢查它,那么您可以依賴IHttpContextAccessor來訪問它。

根據評論更新:

HttpContext本質上在視圖中可用

@if (Context.Connection.IsLocal)
{

}

我還要提到將以下子句添加到自定義IsLocal()檢查的末尾可能會很有用

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

這將解釋使用Microsoft.AspNetCore.TestHost運行站點並且站點完全在本地內存中運行而沒有實際 TCP/IP 連接的情況。

ASP.NET Core 3.1 的更新

你可以使用這個:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM