Let’s assume we want to limit the number of failed login attempts. After five unsuccessful attempts, login access is blocked for 60 minutes.

Rate Limiter

We will use the Rate Limiter component:
composer require symfony/rate-limiter

By default, it provides protection in two ways:
– a limit based on username + IP – protects a specific account against brute-force attacks
– a limit based on IP – protects against mass attempts from a single address

config/packages/security.yaml

    firewalls:
        admin:

            login_throttling:
                max_attempts: 5
                interval: '60 minutes'

Rate Limiter + Azure + Redis

If our application is intended to run on Azure, it is advisable to change the cache_pool from the default filesystem, which is not shared between application instances, to Redis, otherwise, the limiter may not function correctly.

Example Redis connection configuration (in my case, local; Redis is installed via Docker):

.env

###> redis ###
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=""
###< redis ###

We add a new Redis pool, ideally a separate one for the Rate Limiter if we already have one. Additionally, the default_redis_provider key is set to 'redis://localhost' by default; we need to change this.

config/packages/framework.yaml

framework:
    cache:
        default_redis_provider: 'redis://%env(REDIS_HOST)%:%env(int:REDIS_PORT)%?password=%env(REDIS_PASSWORD)%'
        pools:
            redis_rate_limiter:
                adapter: cache.adapter.redis

It remains to specify the cache_pool for the limiter.

config/packages/security.yaml

    firewalls:
        admin:

            login_throttling:
                max_attempts: 5
                interval: '60 minutes'
                cache_pool: 'redis_rate_limiter'

For limiters used, for example, in APIs:

config/packages/rate_limiter.yaml

framework:
    rate_limiter:
        anonymous_api:
            policy: 'sliding_window'
            limit: 1000
            interval: '60 minutes'
            cache_pool: 'redis_rate_limiter'

If necessary, we can clear the pool from the command line using the following command:
php bin/console cache:pool:clear redis_rate_limiter