仅接受ASP.Net Core 2.1 MVC中的本地请求

时间:2018-11-06 07:57:12

标签: c# asp.net-core asp.net-core-mvc

我有一个简单的ASP.Net Core 2.1 MVC应用程序,并且在其中一个控制器中,我想实现一个仅接受本地请求的操作(即,请求源自127.0.0.1或与该地址相同的地址)服务器的IP)。

我一直在ASP.Net Core中寻找一种适合此目的的过滤器,但似乎找不到。我可以使用AuthorizeAttribute,例如[Authorize(Policy = "LocalOnly")]

并在启动中的ConfigureServices中注册相应的策略:

services.AddAuthorization(options =>
{
    options.AddPolicy("LocalOnly", policy =>
    {
        policy.RequireAssertion(context =>
        {
            if (context.Resource is AuthorizationFilterContext mvcContext)
            {
                return mvcContext.HttpContext.Request.IsLocal();
            }
            return false;
        });
    });
});

其中IsLocal()HttpRequest的扩展方法。

但是,我认为这不是正确的方法-我试图做的实际上不是授权,并且由于我的程序中没有身份验证,因此产生的错误是不正确的要么。

是否有一种简单合法的方法来完成我想要的过滤器?还是这实际上应该在控制器的动作逻辑中完成?还是整个检查本地请求的想法不是很正确?

非常感谢您的帮助。

2 个答案:

答案 0 :(得分:1)

用作ASP.NET Core中间件。

在最简单的情况下,使用app.Use(...)方法。

public class Startup
{
    public void Configure(IApplicationBuilder app)
    {
        app.Use(async (context, next) =>
        {
            if (context.Request.IsLocal())
            {
                // Forbidden http status code
                context.Response.StatusCode = 403;
                return;
            }

            await next.Invoke();
        });
    }
}

委托调用根据本地请求返回,从而在此处停止中间件管道。

但是我不确定100%是否要归档。

您是否只想从内部网络调用该服务?更简单的方法是使用docker容器,将需要相互通信的服务添加到同一网络,并且仅将应用程序暴露在确实需要与外界通信的容器外部。

答案 1 :(得分:0)

IsLocal()的扩展方法应如下所示:

public static class HttpRequestExtensions
{
    public static bool IsLocal(this HttpRequest req)
    {
        var connection = req.HttpContext.Connection;
        if (connection.RemoteIpAddress != null)
        {
            if (connection.LocalIpAddress != null)
            {
                return connection.RemoteIpAddress.Equals(connection.LocalIpAddress);
            } 
            else 
            {
                return IPAddress.IsLoopback(connection.RemoteIpAddress);
            }
        }

        // for in memory TestServer or when dealing with default connection info
        if (connection.RemoteIpAddress == null && connection.LocalIpAddress == null)
        {
            return true;
        }

        return false;
    }
}

要确定请求是否是本地的,我们可以检查连接上的RemoteIpAddressLocalIpAddress是否相同,或者如果由于某些原因而未知本地IP,请检查{{ 1}}是回送地址。

您可以在strathweb文章中了解有关此内容的更多信息。

请注意,如果使用RemoteIpAddress,它将不起作用。 如果您确实希望它起作用,请将其更改为:

connection.RemoteIpAddress == "::1"