Реализация ограничения скорости для общедоступных конечных точек в C# и .NET Core для предотвращения атак методом перебора

Мне нужен способ в приложении C#/.NET Core ограничить количество запросов, которые можно сделать к общедоступной конечной точке в течение определенного периода времени. Это необходимо для предотвращения грубой атаки.

Например, пользователь отправляет запрос к конечной точке xx, и она должна разрешить только 3 запроса, отклонив четвертый. Как я могу добиться этого, если это общедоступная конечная точка, где я не могу определить, кто делает запрос?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
98
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете добиться ограничения скорости с помощью nuget AspNetCoreRateLimit, внедрив службу промежуточного программного обеспечения.

Сначала вам нужно добавить пакет в свой проект через:

dotnet add package AspNetCoreRateLimit

или используйте установку этого пакета через интерфейс пользовательского интерфейса управления пакетами nuget в Visual Studio.

Во-вторых, обновите файл appsettings.json, чтобы использовать такую ​​конфигурацию:

{
  "IpRateLimiting": {
    "EnableEndpointRateLimiting": true,
    "StackBlockedRequests": false,
    "RealIpHeader": "X-Real-IP",
    "ClientIdHeader": "X-ClientId",
    "HttpStatusCode": 429,
    "GeneralRules": [
      {
        "Endpoint": "*:/api/publicendpoint",
        "Period": "1m",
        "Limit": 3
      }
    ]
  },
  "IpRateLimitPolicies": {
    "IpRules": []
  }
}

В-третьих, зарегистрируйте сервисы ограничения скорости в своем Startup.cs или Program.cs вот так:

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.Configure<IpRateLimitOptions>(Configuration.GetSection("IpRateLimiting")); // Load configurations added from appsettings.json
        services.Configure<IpRateLimitPolicies>(Configuration.GetSection("IpRateLimitPolicies"));              
        services.AddMemoryCache();   // Specify memory cache to store count limits            
        services.AddInMemoryRateLimiting();  // Add rate limiting services  
        services.AddMvc();          
        services.AddSingleton<IRateLimitConfiguration, RateLimitConfiguration>(); // Specify IpRateLimit middleware as single instance
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        app.UseRouting();    
        app.UseAuthorization();            

        app.UseIpRateLimiting(); // Enable IpRateLimiting middleware which we will implement in fourth stage    

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });
    }
}

В-четвертых, внедрите промежуточное программное обеспечение для ограничения количества запросов следующим образом:

public class RateLimitingMiddleware
{
    private readonly RequestDelegate _next;
    private static readonly MemoryCache _memoryCache = new MemoryCache(new MemoryCacheOptions());
    private static readonly TimeSpan _timeWindow = TimeSpan.FromMinutes(1);
    private static readonly int _maxRequests = 3;

    public RateLimitingMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public async Task InvokeAsync(HttpContext context)
    {
        var ipAddress = context.Connection.RemoteIpAddress.ToString();

        if (IsRateLimited(ipAddress))
        {
            context.Response.StatusCode = 429;
            await context.Response.WriteAsync("Too many requests. Please try again later.");
            return;
        }

        await _next(context);
    }

    private bool IsRateLimited(string ipAddress)
    {
        var cacheKey = $"RateLimit_{ipAddress}";

        if (_memoryCache.TryGetValue(cacheKey, out int requestCount))
        {
            if (requestCount >= _maxRequests)
            {
                return true;
            }

            _memoryCache.Set(cacheKey, ++requestCount, _timeWindow);
        }
        else
        {
            _memoryCache.Set(cacheKey, 1, _timeWindow);
        }

        return false;
    }
}

public static class RateLimitingMiddlewareExtensions
{
    public static IApplicationBuilder UseRateLimiting(this IApplicationBuilder builder)
    {
        return builder.UseMiddleware<RateLimitingMiddleware>();
    }
}

Теперь вы можете указать и указать свое приложение для использования в Startup.cs или Program.cs, как показано здесь:

app.UseRateLimiting();

Можете ли вы объяснить, почему вы предпочитаете AspNetCoreRateLimitвстроенной реализации Microsoft.AspNetCore.RateLimiting?

Dai 21.06.2024 19:51

@Dai Я использую это уже 9 лет. У него есть несколько легко настраиваемых свойств, устанавливаемых через настройки приложений, а также солидная документация. Как говорится, использование встроенного Microsoft.AspNetCore.RateLimiting подойдет и для вопроса ОП.

SELA 21.06.2024 19:58

Можете ли вы проверить этот вопрос, чтобы узнать, знаете ли вы ответ? stackoverflow.com/questions/78754133/…

CodeMonkey 17.07.2024 23:36

Другие вопросы по теме