@@ -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,14 @@ 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
158
+ :class: `Symfony\\ Component\\ HttpFoundation\\ Request ` as ``$subject ``. You
159
+ can learn how to use your custom attributes by reading
160
+ :ref: `security/custom-voter `.
161
+
147
162
.. tip ::
148
163
149
164
If access is denied, the system will try to authenticate the user if not
@@ -180,8 +195,8 @@ pattern so that it is only accessible by requests from the local server itself:
180
195
access_control :
181
196
#
182
197
# 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 }
198
+ - { path: ' ^/internal' , roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1, 192.168.0.1/24] }
199
+ - { path: ' ^/internal' , roles: ROLE_NO_ACCESS }
185
200
186
201
.. code-block :: xml
187
202
@@ -214,13 +229,13 @@ pattern so that it is only accessible by requests from the local server itself:
214
229
'access_control' => [
215
230
[
216
231
'path' => '^/internal',
217
- 'role ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
232
+ 'roles ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
218
233
// the 'ips' option supports IP addresses and subnet masks
219
234
'ips' => ['127.0.0.1', '::1'],
220
235
],
221
236
[
222
237
'path' => '^/internal',
223
- 'role ' => 'ROLE_NO_ACCESS',
238
+ 'roles ' => 'ROLE_NO_ACCESS',
224
239
],
225
240
],
226
241
]);
265
280
access_control :
266
281
-
267
282
path : ^/_internal/secure
268
- allow_if : " '127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')"
283
+ roles : ' ROLE_ADMIN'
284
+ allow_if : " '127.0.0.1' == request.getClientIp() or request.header.has('X-Secure-Access')"
269
285
270
286
.. code-block :: xml
271
287
279
295
280
296
<config >
281
297
<rule path =" ^/_internal/secure"
282
- allow-if =" '127.0.0.1' == request.getClientIp() or has_role('ROLE_ADMIN')" />
298
+ role =" ROLE_ADMIN"
299
+ allow-if =" '127.0.0.1' == request.getClientIp() or request.header.has('X-Secure-Access')" />
283
300
</config >
284
301
</srv : container >
285
302
@@ -288,13 +305,26 @@ key:
288
305
'access_control' => [
289
306
[
290
307
'path' => '^/_internal/secure',
291
- 'allow_if' => '"127.0.0.1" == request.getClientIp() or has_role("ROLE_ADMIN")',
308
+ 'roles' => 'ROLE_ADMIN',
309
+ 'allow_if' => '"127.0.0.1" == request.getClientIp() or request.header.has('X-Secure-Access')',
292
310
],
293
311
],
294
312
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.
313
+ In this case, when the user tries to access any URL starting with
314
+ ``/_internal/secure ``, they will only be granted access if the IP address is
315
+ ``127.0.0.1 `` or a secure header, or if the user has the ``ROLE_ADMIN `` role.
316
+
317
+ .. note ::
318
+
319
+ Internally ``allow_if `` enforce calling the built-in
320
+ :class: `Symfony\\ Component\\ Security\\ Core\\ Authorization\\ Voter\\ ExpressionVoter `
321
+ as like it was part of the attributes defined in the ``roles `` option.
322
+ By default, access is granted if one of the attribute is granted. In other
323
+ words, it means ``allow_if `` can grant access even if the
324
+ :class: `Symfony\\ Component\\ Security\\ Core\\ Authorization\\ Voter\\ RoleVoter ` or
325
+ any other voter denied it.
326
+ To change this behavior, you may need to learn more about
327
+ :ref: `access decision strategy <security-voters-change-strategy >`.
298
328
299
329
Inside the expression, you have access to a number of different variables
300
330
and functions including ``request ``, which is the Symfony
@@ -345,7 +375,7 @@ the user will be redirected to ``https``:
345
375
'access_control' => [
346
376
[
347
377
'path' => '^/cart/checkout',
348
- 'role ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
378
+ 'roles ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
349
379
'requires_channel' => 'https',
350
380
],
351
381
],
0 commit comments