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.redisIt 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

Leave a Reply