@@ -22,10 +22,10 @@ for each ``access_control`` entry, which determines whether or not a given
22
22
access control should be used on this request. The following ``access_control ``
23
23
options are used for matching:
24
24
25
- * ``path ``
25
+ * ``path `` # a regular expression (without delimiters)
26
26
* ``ip `` or ``ips `` (netmasks are also supported)
27
- * ``host ``
28
- * ``methods ``
27
+ * ``host `` # a regular expression
28
+ * ``methods `` # one or many methods
29
29
30
30
Take the following ``access_control `` entries as an example:
31
31
@@ -37,10 +37,10 @@ Take the following ``access_control`` entries as an example:
37
37
security :
38
38
# ...
39
39
access_control :
40
- - { path: ^/admin, roles: ROLE_USER_IP, ip: 127.0.0.1 }
41
- - { path: ^/admin, roles: ROLE_USER_HOST, host: symfony\.com$ }
42
- - { path: ^/admin, roles: ROLE_USER_METHOD, methods: [POST, PUT] }
43
- - { path: ^/admin, roles: ROLE_USER }
40
+ - { path: ' ^/admin' , roles: ROLE_USER_IP, ip: 127.0.0.1 }
41
+ - { path: ' ^/admin' , roles: ROLE_USER_HOST, host: symfony\.com$ }
42
+ - { path: ' ^/admin' , roles: ROLE_USER_METHOD, methods: [POST, PUT] }
43
+ - { path: ' ^/admin' , roles: [ROLE_MANAGER, ROLE_ADMIN] }
44
44
45
45
.. code-block :: xml
46
46
@@ -57,7 +57,12 @@ Take the following ``access_control`` entries as an example:
57
57
<rule path =" ^/admin" role =" ROLE_USER_IP" ip =" 127.0.0.1" />
58
58
<rule path =" ^/admin" role =" ROLE_USER_HOST" host =" symfony\.com$" />
59
59
<rule path =" ^/admin" role =" ROLE_USER_METHOD" methods =" POST, PUT" />
60
- <rule path =" ^/admin" role =" ROLE_USER" />
60
+ <rule path =" ^/admin" roles =" ROLE_ADMIN, ROLE_MANAGER" />
61
+ <!-- same as: -->
62
+ <rule path =" ^/admin" >
63
+ <role >ROLE_MANAGER</role >
64
+ <role >ROLE_ADMIN</role >
65
+ </rule >
61
66
</config >
62
67
</srv : container >
63
68
@@ -69,31 +74,33 @@ Take the following ``access_control`` entries as an example:
69
74
'access_control' => [
70
75
[
71
76
'path' => '^/admin',
72
- 'role ' => 'ROLE_USER_IP',
73
- 'ip ' => '127.0.0.1',
77
+ 'roles ' => 'ROLE_USER_IP',
78
+ 'ips ' => '127.0.0.1',
74
79
],
75
80
[
76
81
'path' => '^/admin',
77
- 'role ' => 'ROLE_USER_HOST',
82
+ 'roles ' => 'ROLE_USER_HOST',
78
83
'host' => 'symfony\.com$',
79
84
],
80
85
[
81
86
'path' => '^/admin',
82
- 'role ' => 'ROLE_USER_METHOD',
87
+ 'roles ' => 'ROLE_USER_METHOD',
83
88
'methods' => 'POST, PUT',
84
89
],
85
90
[
86
91
'path' => '^/admin',
87
- 'role' => 'ROLE_USER',
92
+ 'roles' => 'ROLE_MANAGER, ROLE_ADMIN',
93
+ // same as
94
+ // 'roles' => ['ROLE_MANAGER', 'ROLE_ADMIN'],
88
95
],
89
96
],
90
97
]);
91
98
92
99
For each incoming request, Symfony will decide which ``access_control ``
93
100
to use based on the URI, the client's IP address, the incoming host name,
94
101
and the request method. Remember, the first rule that matches is used, and
95
- if ``ip ``, ``host `` or ``method `` are not specified for an entry, that `` access_control ``
96
- will match any ``ip ``, ``host `` or ``method ``:
102
+ if ``ips ``, ``host `` or ``methods `` are not specified for an entry, that
103
+ `` access_control `` will match any ``ips ``, ``host `` or ``methods ``:
97
104
98
105
+-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
99
106
| URI | IP | HOST | METHOD | ``access_control `` | Why? |
@@ -114,9 +121,9 @@ will match any ``ip``, ``host`` or ``method``:
114
121
| ``/admin/user `` | 168.0.0.1 | example.com | POST | rule #3 (``ROLE_USER_METHOD ``) | The ``ip `` and ``host `` don't match the first two entries, |
115
122
| | | | | | but the third - ``ROLE_USER_METHOD `` - matches and is used. |
116
123
+-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
117
- | ``/admin/user `` | 168.0.0.1 | example.com | GET | rule #4 (``ROLE_USER ``) | The ``ip ``, ``host `` and ``method `` prevent the first |
124
+ | ``/admin/user `` | 168.0.0.1 | example.com | GET | rule #4 (``ROLE_MANAGER ``) | The ``ip ``, ``host `` and ``method `` prevent the first |
118
125
| | | | | | three entries from matching. But since the URI matches the |
119
- | | | | | | ``path `` pattern of the ``ROLE_USER `` entry, it is used. |
126
+ | | | | | | ``path `` pattern, then the ``ROLE_USER `` entry is used. |
120
127
+-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
121
128
| ``/foo `` | 127.0.0.1 | symfony.com | POST | matches no entries | This doesn't match any ``access_control `` rules, since its |
122
129
| | | | | | URI doesn't match any of the ``path `` values. |
@@ -144,6 +151,13 @@ options:
144
151
does not match this value (e.g. ``https ``), the user will be redirected
145
152
(e.g. redirected from ``http `` to ``https ``, or vice versa).
146
153
154
+ .. tip ::
155
+
156
+ Behind the scene, the array value of ``roles `` is passed as ``$attributes ``
157
+ argument to each voter in the application with the :class: `Symfony\C omponent\H ttpFoundation\R equest `
158
+ as ``$subject ``. You can learn how to use your custom attributes by reading
159
+ :ref: `security/custom-voter `.
160
+
147
161
.. tip ::
148
162
149
163
If access is denied, the system will try to authenticate the user if not
@@ -180,8 +194,8 @@ pattern so that it is only accessible by requests from the local server itself:
180
194
access_control :
181
195
#
182
196
# the 'ips' option supports IP addresses and subnet masks
183
- - { path: ^/internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1, 192.168.0.1/24] }
184
- - { path: ^/internal, roles: ROLE_NO_ACCESS }
197
+ - { path: ' ^/internal' , roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1, 192.168.0.1/24] }
198
+ - { path: ' ^/internal' , roles: ROLE_NO_ACCESS }
185
199
186
200
.. code-block :: xml
187
201
@@ -214,13 +228,13 @@ pattern so that it is only accessible by requests from the local server itself:
214
228
'access_control' => [
215
229
[
216
230
'path' => '^/internal',
217
- 'role ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
231
+ 'roles ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
218
232
// the 'ips' option supports IP addresses and subnet masks
219
233
'ips' => ['127.0.0.1', '::1'],
220
234
],
221
235
[
222
236
'path' => '^/internal',
223
- 'role ' => 'ROLE_NO_ACCESS',
237
+ 'roles ' => 'ROLE_NO_ACCESS',
224
238
],
225
239
],
226
240
]);
265
279
access_control :
266
280
-
267
281
path : ^/_internal/secure
268
- allow_if : " '127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')"
282
+ roles : ' ROLE_ADMIN'
283
+ allow_if : " '127.0.0.1' == request.getClientIp() or request.header.has('X-Secure-Access')"
269
284
270
285
.. code-block :: xml
271
286
279
294
280
295
<config >
281
296
<rule path =" ^/_internal/secure"
282
- allow-if =" '127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')" />
297
+ role =" ROLE_ADMIN"
298
+ allow-if =" '127.0.0.1' == request.getClientIp() or request.header.has('X-Secure-Access')" />
283
299
</config >
284
300
</srv : container >
285
301
@@ -288,13 +304,26 @@ key:
288
304
'access_control' => [
289
305
[
290
306
'path' => '^/_internal/secure',
291
- 'allow_if' => '"127.0.0.1" == request.getClientIp() or has_role("ROLE_ADMIN")',
307
+ 'roles' => 'ROLE_ADMIN',
308
+ 'allow_if' => '"127.0.0.1" == request.getClientIp() or request.header.has('X-Secure-Access')',
292
309
],
293
310
],
294
311
295
- In this case, when the user tries to access any URL starting with ``/_internal/secure ``,
296
- they will only be granted access if the IP address is ``127.0.0.1 `` or if
297
- the user has the ``ROLE_ADMIN `` role.
312
+ In this case, when the user tries to access any URL starting with
313
+ ``/_internal/secure ``, they will only be granted access if the IP address is
314
+ ``127.0.0.1 `` or a secure header, or if the user has the ``ROLE_ADMIN `` role.
315
+
316
+ .. note ::
317
+
318
+ Internally ``allow_if `` enforce calling the built-in
319
+ :class: `Symfony\\ Component\\ Security\\ Core\\ Authorization\\ Voter\\ ExpressionVoter `
320
+ as like it was part of the attributes defined in the ``roles `` option.
321
+ By default, access is granted if one of the attribute is granted. In other
322
+ words, it means ``allow_if `` can grant access even if the
323
+ :class: `Symfony\\ Component\\ Security\\ Core\\ Authorization\\ Voter\\ RoleVoter ` or
324
+ any other voter denied it.
325
+ To change this behavior, you may need to learn more about
326
+ :ref: `access decision strategy <security-voters-change-strategy >`.
298
327
299
328
Inside the expression, you have access to a number of different variables
300
329
and functions including ``request ``, which is the Symfony
@@ -345,7 +374,7 @@ the user will be redirected to ``https``:
345
374
'access_control' => [
346
375
[
347
376
'path' => '^/cart/checkout',
348
- 'role ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
377
+ 'roles ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
349
378
'requires_channel' => 'https',
350
379
],
351
380
],
0 commit comments