11
11
12
12
namespace Symfony \Bundle \SecurityBundle \DependencyInjection \Security \Factory ;
13
13
14
+ use Symfony \Bridge \Doctrine \Security \RememberMe \DoctrineTokenProvider ;
14
15
use Symfony \Component \Config \Definition \Builder \NodeDefinition ;
16
+ use Symfony \Component \Config \Definition \Exception \InvalidConfigurationException ;
15
17
use Symfony \Component \Config \FileLocator ;
16
18
use Symfony \Component \DependencyInjection \Argument \IteratorArgument ;
17
19
use Symfony \Component \DependencyInjection \ChildDefinition ;
@@ -109,8 +111,9 @@ public function createAuthenticator(ContainerBuilder $container, string $firewal
109
111
$ container ->setDefinition ($ rememberMeHandlerId , $ container ->getDefinition ($ options ['service ' ]))
110
112
->addTag ('security.remember_me_handler ' , ['firewall ' => $ firewallName ]);
111
113
} elseif (isset ($ options ['token_provider ' ])) {
114
+ $ tokenProviderId = $ this ->createTokenProvider ($ container , $ firewallName , $ config ['token_provider ' ]);
112
115
$ container ->setDefinition ($ rememberMeHandlerId , new ChildDefinition ('security.authenticator.persistent_remember_me_handler ' ))
113
- ->replaceArgument (0 , new Reference ($ options [ ' token_provider ' ] ))
116
+ ->replaceArgument (0 , new Reference ($ tokenProviderId ))
114
117
->replaceArgument (2 , new Reference ($ userProviderId ))
115
118
->replaceArgument (4 , $ options )
116
119
->addTag ('security.remember_me_handler ' , ['firewall ' => $ firewallName ]);
@@ -175,7 +178,6 @@ public function addConfiguration(NodeDefinition $node)
175
178
$ builder
176
179
->scalarNode ('secret ' )->isRequired ()->cannotBeEmpty ()->end ()
177
180
->scalarNode ('service ' )->end ()
178
- ->scalarNode ('token_provider ' )->end ()
179
181
->arrayNode ('user_providers ' )
180
182
->beforeNormalization ()
181
183
->ifString ()->then (function ($ v ) { return [$ v ]; })
@@ -191,6 +193,23 @@ public function addConfiguration(NodeDefinition $node)
191
193
->end ()
192
194
;
193
195
196
+ $ tokenProviderBuilder = $ builder
197
+ ->arrayNode ('token_provider ' )
198
+ ->beforeNormalization ()
199
+ ->ifString ()->then (function ($ v ) { return ['service ' => $ v ]; })
200
+ ->end ()
201
+ ->children ()
202
+ ->scalarNode ('service ' )->end ();
203
+ if (class_exists (DoctrineTokenProvider::class)) {
204
+ $ tokenProviderBuilder
205
+ ->arrayNode ('doctrine ' )
206
+ ->canBeEnabled ()
207
+ ->children ()
208
+ ->scalarNode ('connection ' )->defaultValue ('default ' )->end ()
209
+ ->end ()
210
+ ->end ();
211
+ }
212
+
194
213
foreach ($ this ->options as $ name => $ value ) {
195
214
if ('secure ' === $ name ) {
196
215
$ builder ->enumNode ($ name )->values ([true , false , 'auto ' ])->defaultValue ('auto ' === $ value ? null : $ value );
@@ -228,9 +247,8 @@ private function createRememberMeServices(ContainerBuilder $container, string $i
228
247
$ rememberMeServices ->replaceArgument (2 , $ id );
229
248
230
249
if (isset ($ config ['token_provider ' ])) {
231
- $ rememberMeServices ->addMethodCall ('setTokenProvider ' , [
232
- new Reference ($ config ['token_provider ' ]),
233
- ]);
250
+ $ tokenProviderId = $ this ->createTokenProvider ($ container , $ id , $ config ['token_provider ' ]);
251
+ $ rememberMeServices ->addMethodCall ('setTokenProvider ' , [new Reference ($ tokenProviderId )]);
234
252
}
235
253
236
254
// remember-me options
@@ -249,4 +267,24 @@ private function createRememberMeServices(ContainerBuilder $container, string $i
249
267
250
268
$ rememberMeServices ->replaceArgument (0 , new IteratorArgument (array_unique ($ userProviders )));
251
269
}
270
+
271
+ private function createTokenProvider (ContainerBuilder $ container , string $ firewallName , array $ config ): string
272
+ {
273
+ $ tokenProviderId = $ config ['service ' ];
274
+ if ($ config ['doctrine ' ]['enabled ' ] ?? false ) {
275
+ if (!class_exists (DoctrineTokenProvider::class)) {
276
+ throw new InvalidConfigurationException ('"remember_me.token_provider.doctrine" cannot be enabled as symfony/doctrine-bridge is not installed. ' );
277
+ }
278
+
279
+ $ tokenProviderId = 'security.remember_me.doctrine_token_provider. ' .$ firewallName ;
280
+ $ container ->register ($ tokenProviderId , DoctrineTokenProvider::class)
281
+ ->addArgument (new Reference ('doctrine.dbal. ' .$ config ['doctrine ' ]['connection ' ].'_connection ' ));
282
+ }
283
+
284
+ if (!$ tokenProviderId ) {
285
+ throw new InvalidConfigurationException (sprintf ('No token provider was set for firewall "%s". Either configure a service ID or set "remember_me.token_provider.doctrine" to true. ' , $ firewallName ));
286
+ }
287
+
288
+ return $ tokenProviderId ;
289
+ }
252
290
}
0 commit comments