Принимайте только локальный запрос в ASP.Net Core 2.1 MVC - PullRequest
0 голосов
/ 06 ноября 2018

У меня есть простое приложение 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 голосов
/ 06 ноября 2018

Сделайте это как промежуточное ПО 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, добавить сервисы, которые должны взаимодействовать друг с другом, в одну и ту же сеть и открыть приложение только вне контейнера, который действительно должен взаимодействовать с внешним миром.

0 голосов
/ 06 ноября 2018

Метод расширения 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;
    }
}

Чтобы определить, является ли запрос локальным, мы можем проверить, совпадают ли RemoteIpAddress и LocalIpAddress в соединении, или, если по какой-либо причине локальный IP-адрес неизвестен, если RemoteIpAddress является шлейфом адрес.

Подробнее об этом можно прочитать в статье strathweb .

Обратите внимание, что это не будет работать, если connection.RemoteIpAddress == "::1". Если вы хотите, чтобы он работал, измените его на:

Request.Host.Value.StartsWith(“localhost:”)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...