11
11
12
12
namespace Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory ;
13
13
14
- use Symfony \Bundle \FrameworkBundle \DependencyInjection \FrameworkExtension ;
15
14
use Symfony \Component \Config \Definition \Builder \ArrayNodeDefinition ;
16
15
use Symfony \Component \Config \Definition \Builder \NodeDefinition ;
17
16
use Symfony \Component \DependencyInjection \ChildDefinition ;
18
17
use Symfony \Component \DependencyInjection \ContainerBuilder ;
18
+ use Symfony \Component \DependencyInjection \Exception \LogicException ;
19
19
use Symfony \Component \DependencyInjection \Reference ;
20
20
use Symfony \Component \HttpFoundation \RateLimiter \RequestRateLimiterInterface ;
21
+ use Symfony \Component \Lock \LockInterface ;
21
22
use Symfony \Component \RateLimiter \RateLimiterFactory ;
23
+ use Symfony \Component \RateLimiter \Storage \CacheStorage ;
22
24
use Symfony \Component \Security \Http \RateLimiter \DefaultLoginRateLimiter ;
23
25
24
26
/**
@@ -60,20 +62,16 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
60
62
}
61
63
62
64
if (!isset ($ config ['limiter ' ])) {
63
- if (!class_exists (FrameworkExtension::class) || !method_exists (FrameworkExtension::class, 'registerRateLimiter ' )) {
64
- throw new \LogicException ('You must either configure a rate limiter for "security.firewalls. ' .$ firewallName .'.login_throttling" or install symfony/framework-bundle:^5.2. ' );
65
- }
66
-
67
65
$ limiterOptions = [
68
66
'policy ' => 'fixed_window ' ,
69
67
'limit ' => $ config ['max_attempts ' ],
70
68
'interval ' => $ config ['interval ' ],
71
69
'lock_factory ' => $ config ['lock_factory ' ],
72
70
];
73
- FrameworkExtension:: registerRateLimiter ($ container , $ localId = '_login_local_ ' .$ firewallName , $ limiterOptions );
71
+ $ this -> registerRateLimiter ($ container , $ localId = '_login_local_ ' .$ firewallName , $ limiterOptions );
74
72
75
73
$ limiterOptions ['limit ' ] = 5 * $ config ['max_attempts ' ];
76
- FrameworkExtension:: registerRateLimiter ($ container , $ globalId = '_login_global_ ' .$ firewallName , $ limiterOptions );
74
+ $ this -> registerRateLimiter ($ container , $ globalId = '_login_global_ ' .$ firewallName , $ limiterOptions );
77
75
78
76
$ container ->register ($ config ['limiter ' ] = 'security.login_throttling. ' .$ firewallName .'.limiter ' , DefaultLoginRateLimiter::class)
79
77
->addArgument (new Reference ('limiter. ' .$ globalId ))
@@ -88,4 +86,33 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
88
86
89
87
return [];
90
88
}
89
+
90
+ private function registerRateLimiter (ContainerBuilder $ container , string $ name , array $ limiterConfig )
91
+ {
92
+ // default configuration (when used by other DI extensions)
93
+ $ limiterConfig += ['lock_factory ' => 'lock.factory ' , 'cache_pool ' => 'cache.rate_limiter ' ];
94
+
95
+ $ limiter = $ container ->setDefinition ($ limiterId = 'limiter. ' .$ name , new ChildDefinition ('limiter ' ));
96
+
97
+ if (null !== $ limiterConfig ['lock_factory ' ]) {
98
+ if (!interface_exists (LockInterface::class)) {
99
+ throw new LogicException (sprintf ('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock". ' , $ name ));
100
+ }
101
+
102
+ $ limiter ->replaceArgument (2 , new Reference ($ limiterConfig ['lock_factory ' ]));
103
+ }
104
+ unset($ limiterConfig ['lock_factory ' ]);
105
+
106
+ if (null === $ storageId = $ limiterConfig ['storage_service ' ] ?? null ) {
107
+ $ container ->register ($ storageId = 'limiter.storage. ' .$ name , CacheStorage::class)->addArgument (new Reference ($ limiterConfig ['cache_pool ' ]));
108
+ }
109
+
110
+ $ limiter ->replaceArgument (1 , new Reference ($ storageId ));
111
+ unset($ limiterConfig ['storage_service ' ], $ limiterConfig ['cache_pool ' ]);
112
+
113
+ $ limiterConfig ['id ' ] = $ name ;
114
+ $ limiter ->replaceArgument (0 , $ limiterConfig );
115
+
116
+ $ container ->registerAliasForArgument ($ limiterId , RateLimiterFactory::class, $ name .'.limiter ' );
117
+ }
91
118
}
0 commit comments