Skip to content

Commit c9e46cf

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

File tree

2 files changed

+219
-0
lines changed

2 files changed

+219
-0
lines changed

Diff for: cookbook/security/index.rst

+1
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
------------------------------

Diff for: cookbook/security/user_checkers.rst

+218
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
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+
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+
</service>
85+
</services>
86+
</container>
87+
88+
.. code-block:: php
89+
90+
// app/config/services.php
91+
use Symfony\Component\DependencyInjection\Definition;
92+
93+
$userChecker = new Definition('App\Security\UserChecker');
94+
$container->setDefinition('app.user_checker', $userChecker);
95+
96+
All that's left to do is add the checker to the desired firewall where the value
97+
is the service id of your user checker:
98+
99+
.. configuration-block::
100+
101+
.. code-block:: yaml
102+
103+
# app/config/security.yml
104+
105+
# ...
106+
security:
107+
firewalls:
108+
secured_area:
109+
pattern: ^/
110+
user_checkers: ["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: ["app.user_checker", "app.admin_checker"]
168+
# ...
169+
secured_area:
170+
pattern: ^/
171+
user_checkers: ["app.user_checker"]
172+
173+
.. code-block:: xml
174+
175+
<!-- app/config/security.xml -->
176+
<?xml version="1.0" encoding="UTF-8"?>
177+
<srv:container xmlns="http://symfony.com/schema/dic/security"
178+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
179+
xmlns:srv="http://symfony.com/schema/dic/services"
180+
xsi:schemaLocation="http://symfony.com/schema/dic/services
181+
http://symfony.com/schema/dic/services/services-1.0.xsd">
182+
183+
<config>
184+
<!-- ... -->
185+
<firewall name="admin" pattern="^/admin">
186+
<user-checkers>app.user_checker</user-checkers>
187+
<user-checkers>app.admin_checker</user-checkers>
188+
<!-- ... -->
189+
</firewall>
190+
<firewall name="secured_area" pattern="^/">
191+
<user-checkers>app.user_checker</user-checkers>
192+
<!-- ... -->
193+
</firewall>
194+
</config>
195+
</srv:container>
196+
197+
.. code-block:: php
198+
199+
// app/config/security.php
200+
201+
// ...
202+
$container->loadFromExtension('security', array(
203+
'firewalls' => array(
204+
'admin' => array(
205+
'pattern' => '^/admin',
206+
'user_checkers' => array(
207+
'app.user_checker',
208+
'app.admin_checker',
209+
),
210+
// ...
211+
),
212+
'secured_area' => array(
213+
'pattern' => '^/',
214+
'user_checkers' => array('app.user_checker'),
215+
// ...
216+
),
217+
),
218+
));

0 commit comments

Comments
 (0)