@@ -116,3 +116,148 @@ is the service id of your user checker:
116116 // ...
117117 ;
118118 };
119+
120+ Using Multiple User Checkers
121+ ----------------------------
122+
123+ .. versionadded :: 6.2
124+
125+ The ``ChainUserChecker `` class was added in Symfony 6.2.
126+
127+ It is common for applications to have multiple authentication entry points (such as
128+ traditional form based login and an API) which may have unique checker rules for each
129+ entry point as well as common rules for all entry points. To allow using multiple user
130+ checkers on a firewall, a service for the :class: `Symfony\\ Component\\ Security\\ Core\\ User\\ ChainUserChecker `
131+ class is created for each firewall.
132+
133+ To use the chain user checker, first you will need to tag your user checker services with the
134+ ``security.user_checker.<firewall> `` tag (where ``<firewall> `` is the name of the firewall
135+ in your security configuration). The service tag also supports the priority attribute, allowing you to define the
136+ order in which user checkers are called::
137+
138+ .. configuration-block ::
139+
140+ .. code-block :: yaml
141+
142+ # config/services.yaml
143+
144+ # ...
145+ services :
146+ App\Security\AccountEnabledUserChecker :
147+ tags :
148+ - { name: security.user_checker.api, priority: 10 }
149+ - { name: security.user_checker.main, priority: 10 }
150+
151+ App\Security\APIAccessAllowedUserChecker :
152+ tags :
153+ - { name: security.user_checker.api, priority: 5 }
154+
155+ .. code-block :: xml
156+
157+ <!-- config/services.xml -->
158+ <?xml version =" 1.0" encoding =" UTF-8" ?>
159+ <container xmlns =" http://symfony.com/schema/dic/services"
160+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
161+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
162+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
163+
164+ <services >
165+ <!-- ... -->
166+
167+ <service id =" App\Security\AccountEnabledUserChecker" >
168+ <tag name =" security.user_checker.api" priority =" 10" />
169+ <tag name =" security.user_checker.main" priority =" 10" />
170+ </service >
171+
172+ <service id =" App\Security\APIAccessAllowedUserChecker" >
173+ <tag name =" security.user_checker.api" priority =" 5" />
174+ </service >
175+ </services >
176+ </container >
177+
178+ .. code-block :: php
179+
180+ // config/services.php
181+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
182+
183+ use App\Security\AccountEnabledUserChecker;
184+ use App\Security\APIAccessAllowedUserChecker;
185+
186+ return function(ContainerConfigurator $configurator) {
187+ $services = $configurator->services();
188+
189+ $services->set(AccountEnabledUserChecker::class)
190+ ->tag('security.user_checker.api', ['priority' => 10])
191+ ->tag('security.user_checker.main', ['priority' => 10]);
192+
193+ $services->set(APIAccessAllowedUserChecker::class)
194+ ->tag('security.user_checker.api', ['priority' => 5]);
195+ };
196+
197+ Once your checker services are tagged, next you will need configure your firewalls to use the
198+ ``security.user_checker.chain.<firewall> `` service::
199+
200+ .. configuration-block ::
201+
202+ .. code-block :: yaml
203+
204+ # config/packages/security.yaml
205+
206+ # ...
207+ security :
208+ firewalls :
209+ api :
210+ pattern : ^/api
211+ user_checker : security.user_checker.chain.api
212+ # ...
213+ main :
214+ pattern : ^/
215+ user_checker : security.user_checker.chain.main
216+ # ...
217+
218+ .. code-block :: xml
219+
220+ <!-- config/packages/security.xml -->
221+ <?xml version =" 1.0" encoding =" UTF-8" ?>
222+ <srv : container xmlns =" http://symfony.com/schema/dic/security"
223+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
224+ xmlns : srv =" http://symfony.com/schema/dic/services"
225+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
226+ https://symfony.com/schema/dic/services/services-1.0.xsd
227+ http://symfony.com/schema/dic/security
228+ https://symfony.com/schema/dic/security/security-1.0.xsd" >
229+
230+ <config >
231+ <!-- ... -->
232+ <firewall name =" api"
233+ pattern =" ^/api"
234+ user-checker =" security.user_checker.chain.api" >
235+ <!-- ... -->
236+ </firewall >
237+ <firewall name =" main"
238+ pattern =" ^/"
239+ user-checker =" security.user_checker.chain.main" >
240+ <!-- ... -->
241+ </firewall >
242+ </config >
243+ </srv : container >
244+
245+ .. code-block :: php
246+
247+ // config/packages/security.php
248+ use Symfony\Config\SecurityConfig;
249+
250+ return static function (SecurityConfig $security) {
251+ // ...
252+ $security->firewall('api')
253+ ->pattern('^/api')
254+ ->userChecker('security.user_checker.chain.api')
255+ // ...
256+ ;
257+
258+ $security->firewall('main')
259+ ->pattern('^/')
260+ ->userChecker('security.user_checker.chain.main')
261+ // ...
262+ ;
263+ };
0 commit comments