Skip to content

Commit 6230f5b

Browse files
author
Iltar van der Berg
committed
Added user_checkers.rst
1 parent befbf7b commit 6230f5b

File tree

2 files changed

+222
-0
lines changed

2 files changed

+222
-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: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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 custom user checkers, you
9+
can define per firewall which checkers should be used.
10+
11+
.. versionadded:: 2.8
12+
Adding custom user checkers was introduced in Symfony 2.8.
13+
14+
15+
Creating a Custom User Checker
16+
------------------------------
17+
18+
Symfony provides an interface that enables you to implement a custom user checker
19+
:class:`UserCheckerInterface Symfony\\Component\\Security\\Core\\UserCheckerInterface`,
20+
this interface is required. If one or more conditions are not met, an exception should
21+
be throw which extends the
22+
:class:`AccountStatusException Symfony\\Component\\Security\\Core\\Exception\\AccountStatusException`
23+
24+
.. code-block:: php
25+
26+
namespace App\Security;
27+
28+
use Symfony\Component\Security\Core\User\UserCheckInterface;
29+
30+
class UserChecker implements UserCheckerInterface
31+
{
32+
public function checkPreAuth(UserInterface $user)
33+
{
34+
if (!$user instanceof AppUser) {
35+
return;
36+
}
37+
38+
// user is deleted, show a generic Account Not Found message.
39+
if ($user->isDeleted()) {
40+
throw new AccountDeletedException('...');
41+
}
42+
}
43+
44+
public function checkPostAuth(UserInterface $user)
45+
{
46+
if (!$user instanceof AppUser) {
47+
return;
48+
}
49+
50+
// user account is expired, the user may be notified
51+
if ($user->isExpired()) {
52+
throw new AccountExpiredException('...');
53+
}
54+
}
55+
}
56+
57+
Enabling the Custom User Checker
58+
--------------------------------
59+
60+
All that's left to be done is creating a service definition and configuring
61+
this in the firewall configuration. Configuring the service is done like any
62+
other service:
63+
64+
.. configuration-block::
65+
66+
.. code-block:: yaml
67+
68+
# app/config/services.yml
69+
services:
70+
app.user_checker:
71+
class: App\Security\UserChecker
72+
73+
.. code-block:: xml
74+
75+
<!-- app/config/services.xml -->
76+
<?xml version="1.0" encoding="UTF-8" ?>
77+
<container xmlns="http://symfony.com/schema/dic/services"
78+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
79+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
80+
81+
<services>
82+
<service id="app.user_checker" class="App\Security\UserChecker">
83+
</service>
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_checkers:
110+
- "app.user_checker"
111+
# ...
112+
113+
.. code-block:: xml
114+
115+
<!-- app/config/security.xml -->
116+
<?xml version="1.0" encoding="UTF-8"?>
117+
<srv:container xmlns="http://symfony.com/schema/dic/security"
118+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
119+
xmlns:srv="http://symfony.com/schema/dic/services"
120+
xsi:schemaLocation="http://symfony.com/schema/dic/services
121+
http://symfony.com/schema/dic/services/services-1.0.xsd">
122+
123+
<config>
124+
<!-- ... -->
125+
<firewall name="secured_area" pattern="^/">
126+
<user-checkers>app.user_checker</user-checkers>
127+
<!-- ... -->
128+
</firewall>
129+
</config>
130+
</srv:container>
131+
132+
.. code-block:: php
133+
134+
// app/config/security.php
135+
136+
// ...
137+
$container->loadFromExtension('security', array(
138+
'firewalls' => array(
139+
'secured_area' => array(
140+
'pattern' => '^/',
141+
'user_checkers' => array('app.user_checker'),
142+
// ...
143+
),
144+
),
145+
));
146+
147+
148+
Additional Configurations
149+
-------------------------
150+
151+
It's possible to add multiple user checkers to one firewall while
152+
configuring only one user checker for another firewall. When adding
153+
multiple user checkers, they are executed in the same sequence as
154+
defined in your configuration.
155+
156+
.. configuration-block::
157+
158+
.. code-block:: yaml
159+
160+
# app/config/security.yml
161+
162+
# ...
163+
security:
164+
firewalls:
165+
admin:
166+
pattern: ^/admin
167+
user_checkers:
168+
- "app.user_checker"
169+
- "app.admin_checker"
170+
# ...
171+
secured_area:
172+
pattern: ^/
173+
user_checkers:
174+
- "app.user_checker"
175+
176+
.. code-block:: xml
177+
178+
<!-- app/config/security.xml -->
179+
<?xml version="1.0" encoding="UTF-8"?>
180+
<srv:container xmlns="http://symfony.com/schema/dic/security"
181+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
182+
xmlns:srv="http://symfony.com/schema/dic/services"
183+
xsi:schemaLocation="http://symfony.com/schema/dic/services
184+
http://symfony.com/schema/dic/services/services-1.0.xsd">
185+
186+
<config>
187+
<!-- ... -->
188+
<firewall name="admin" pattern="^/admin">
189+
<user-checkers>app.user_checker</user-checkers>
190+
<user-checkers>app.admin_checker</user-checkers>
191+
<!-- ... -->
192+
</firewall>
193+
<firewall name="secured_area" pattern="^/">
194+
<user-checkers>app.user_checker</user-checkers>
195+
<!-- ... -->
196+
</firewall>
197+
</config>
198+
</srv:container>
199+
200+
.. code-block:: php
201+
202+
// app/config/security.php
203+
204+
// ...
205+
$container->loadFromExtension('security', array(
206+
'firewalls' => array(
207+
'admin' => array(
208+
'pattern' => '^/admin',
209+
'user_checkers' => array(
210+
'app.user_checker',
211+
'app.admin_checker',
212+
),
213+
// ...
214+
),
215+
'secured_area' => array(
216+
'pattern' => '^/',
217+
'user_checkers' => array('app.user_checker'),
218+
// ...
219+
),
220+
),
221+
));

0 commit comments

Comments
 (0)