Skip to content

Commit 89b20a8

Browse files
Iltar van der Bergxabbuh
authored andcommitted
[Cookbook, Security] Added user_checkers.rst
1 parent 25fe737 commit 89b20a8

File tree

2 files changed

+216
-0
lines changed

2 files changed

+216
-0
lines changed

cookbook/security/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ Authentication (Identifying/Logging in the User)
2323
multiple_user_providers
2424
firewall_restriction
2525
host_restriction
26+
user_checkers
2627

2728
Authorization (Denying Access)
2829
------------------------------

cookbook/security/user_checkers.rst

Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
.. index::
2+
single: Security; Creating and Enabling Custom User Checkers
3+
4+
How to Create and Enable Custom User Checkers
5+
=============================================
6+
7+
During the authentication of a user, additional checks might be required to verify
8+
if the identified user is allowed to log in. By defining a custom user checker, you
9+
can define per firewall which checker should be used.
10+
11+
.. versionadded:: 2.8
12+
Defining a custom user checker was introduced in Symfony 2.8.
13+
14+
15+
Creating a Custom User Checker
16+
------------------------------
17+
18+
User checkers are defined in PHP classes that must implement the
19+
:class:`UserCheckerInterface Symfony\\Component\\Security\\Core\\UserCheckerInterface`.
20+
This interface defines two methods called ``checkPreAuth()`` and ``checkPostAuth()``
21+
to perform checks before and after user authentication. If one or more
22+
conditions are not met, an exception should be thrown which extends the
23+
:class:`AccountStatusException Symfony\\Component\\Security\\Core\\Exception\\AccountStatusException`
24+
25+
.. code-block:: php
26+
27+
namespace App\Security;
28+
29+
use Symfony\Component\Security\Core\User\UserCheckInterface;
30+
31+
class UserChecker implements UserCheckerInterface
32+
{
33+
public function checkPreAuth(UserInterface $user)
34+
{
35+
if (!$user instanceof AppUser) {
36+
return;
37+
}
38+
39+
// user is deleted, show a generic Account Not Found message.
40+
if ($user->isDeleted()) {
41+
throw new AccountDeletedException('...');
42+
}
43+
}
44+
45+
public function checkPostAuth(UserInterface $user)
46+
{
47+
if (!$user instanceof AppUser) {
48+
return;
49+
}
50+
51+
// user account is expired, the user may be notified
52+
if ($user->isExpired()) {
53+
throw new AccountExpiredException('...');
54+
}
55+
}
56+
}
57+
58+
Enabling the Custom User Checker
59+
--------------------------------
60+
61+
All that's left to be done is creating a service definition and configuring
62+
this in the firewall configuration. Configuring the service is done like any
63+
other service:
64+
65+
.. configuration-block::
66+
67+
.. code-block:: yaml
68+
69+
# app/config/services.yml
70+
services:
71+
app.user_checker:
72+
class: App\Security\UserChecker
73+
74+
.. code-block:: xml
75+
76+
<!-- app/config/services.xml -->
77+
<?xml version="1.0" encoding="UTF-8" ?>
78+
<container xmlns="http://symfony.com/schema/dic/services"
79+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
80+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
81+
82+
<services>
83+
<service id="app.user_checker" class="App\Security\UserChecker" />
84+
</services>
85+
</container>
86+
87+
.. code-block:: php
88+
89+
// app/config/services.php
90+
use Symfony\Component\DependencyInjection\Definition;
91+
92+
$userChecker = new Definition('App\Security\UserChecker');
93+
$container->setDefinition('app.user_checker', $userChecker);
94+
95+
All that's left to do is add the checker to the desired firewall where the value
96+
is the service id of your user checker:
97+
98+
.. configuration-block::
99+
100+
.. code-block:: yaml
101+
102+
# app/config/security.yml
103+
104+
# ...
105+
security:
106+
firewalls:
107+
secured_area:
108+
pattern: ^/
109+
user_checker: app.user_checker
110+
# ...
111+
112+
.. code-block:: xml
113+
114+
<!-- app/config/security.xml -->
115+
<?xml version="1.0" encoding="UTF-8"?>
116+
<srv:container xmlns="http://symfony.com/schema/dic/security"
117+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
118+
xmlns:srv="http://symfony.com/schema/dic/services"
119+
xsi:schemaLocation="http://symfony.com/schema/dic/services
120+
http://symfony.com/schema/dic/services/services-1.0.xsd">
121+
122+
<config>
123+
<!-- ... -->
124+
<firewall name="secured_area" pattern="^/">
125+
<user-checker>app.user_checker</user-checker>
126+
<!-- ... -->
127+
</firewall>
128+
</config>
129+
</srv:container>
130+
131+
.. code-block:: php
132+
133+
// app/config/security.php
134+
135+
// ...
136+
$container->loadFromExtension('security', array(
137+
'firewalls' => array(
138+
'secured_area' => array(
139+
'pattern' => '^/',
140+
'user_checker' => 'app.user_checker',
141+
// ...
142+
),
143+
),
144+
));
145+
146+
147+
Additional Configurations
148+
-------------------------
149+
150+
It's possible to have a different user checker per firewall.
151+
152+
.. configuration-block::
153+
154+
.. code-block:: yaml
155+
156+
# app/config/security.yml
157+
158+
# ...
159+
security:
160+
firewalls:
161+
admin:
162+
pattern: ^/admin
163+
user_checker: app.admin_user_checker
164+
# ...
165+
secured_area:
166+
pattern: ^/
167+
user_checker: app.user_checker
168+
169+
.. code-block:: xml
170+
171+
<!-- app/config/security.xml -->
172+
<?xml version="1.0" encoding="UTF-8"?>
173+
<srv:container xmlns="http://symfony.com/schema/dic/security"
174+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
175+
xmlns:srv="http://symfony.com/schema/dic/services"
176+
xsi:schemaLocation="http://symfony.com/schema/dic/services
177+
http://symfony.com/schema/dic/services/services-1.0.xsd">
178+
179+
<config>
180+
<!-- ... -->
181+
<firewall name="admin" pattern="^/admin">
182+
<user-checker>app.admin_user_checker</user-checker>
183+
<!-- ... -->
184+
</firewall>
185+
<firewall name="secured_area" pattern="^/">
186+
<user-checker>app.user_checker</user-checker>
187+
<!-- ... -->
188+
</firewall>
189+
</config>
190+
</srv:container>
191+
192+
.. code-block:: php
193+
194+
// app/config/security.php
195+
196+
// ...
197+
$container->loadFromExtension('security', array(
198+
'firewalls' => array(
199+
'admin' => array(
200+
'pattern' => '^/admin',
201+
'user_checkers' => 'app.admin_user_checker'
202+
// ...
203+
),
204+
'secured_area' => array(
205+
'pattern' => '^/',
206+
'user_checker' => 'app.user_checker',
207+
// ...
208+
),
209+
),
210+
));
211+
212+
.. note::
213+
214+
Internally the user checkers are aliased per firewall. For `secured_area` the alias
215+
`security.user_checker.secured_area` would point to `app.user_checker`.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy