@@ -24,11 +24,11 @@ for each ``access_control`` entry, which determines whether or not a given
24
24
access control should be used on this request. The following ``access_control ``
25
25
options are used for matching:
26
26
27
- * ``path ``
28
- * ``ip `` or ``ips `` ( netmasks are also supported)
29
- * ``port ``
30
- * ``host ``
31
- * ``methods ``
27
+ * ``path ``: a regular expression (without delimiters)
28
+ * ``ip `` or ``ips ``: netmasks are also supported
29
+ * ``port ``: an integer
30
+ * ``host ``: a regular expression
31
+ * ``methods ``: one or many methods
32
32
33
33
Take the following ``access_control `` entries as an example:
34
34
@@ -40,11 +40,12 @@ Take the following ``access_control`` entries as an example:
40
40
security :
41
41
# ...
42
42
access_control :
43
- - { path: ^/admin, roles: ROLE_USER_IP, ip: 127.0.0.1 }
44
- - { path: ^/admin, roles: ROLE_USER_PORT, ip: 127.0.0.1, port: 8080 }
45
- - { path: ^/admin, roles: ROLE_USER_HOST, host: symfony\.com$ }
46
- - { path: ^/admin, roles: ROLE_USER_METHOD, methods: [POST, PUT] }
47
- - { path: ^/admin, roles: ROLE_USER }
43
+ - { path: '^/admin', roles: ROLE_USER_IP, ip: 127.0.0.1 }
44
+ - { path: '^/admin', roles: ROLE_USER_PORT, ip: 127.0.0.1, port: 8080 }
45
+ - { path: '^/admin', roles: ROLE_USER_HOST, host: symfony\.com$ }
46
+ - { path: '^/admin', roles: ROLE_USER_METHOD, methods: [POST, PUT] }
47
+ # when defining multiple roles, users must have at least one of them (it's like an OR condition)
48
+ - { path: '^/admin', roles: [ROLE_MANAGER, ROLE_ADMIN] }
48
49
49
50
.. code-block :: xml
50
51
@@ -62,7 +63,8 @@ Take the following ``access_control`` entries as an example:
62
63
<rule path =" ^/admin" role =" ROLE_USER_PORT" ip =" 127.0.0.1" port =" 8080" />
63
64
<rule path =" ^/admin" role =" ROLE_USER_HOST" host =" symfony\.com$" />
64
65
<rule path =" ^/admin" role =" ROLE_USER_METHOD" methods =" POST, PUT" />
65
- <rule path =" ^/admin" role =" ROLE_USER" />
66
+ <!-- when defining multiple roles, users must have at least one of them (it's like an OR condition) -->
67
+ <rule path =" ^/admin" roles =" ROLE_ADMIN, ROLE_MANAGER" />
66
68
</config >
67
69
</srv : container >
68
70
@@ -74,28 +76,29 @@ Take the following ``access_control`` entries as an example:
74
76
'access_control' => [
75
77
[
76
78
'path' => '^/admin',
77
- 'role ' => 'ROLE_USER_IP',
78
- 'ip ' => '127.0.0.1',
79
+ 'roles ' => 'ROLE_USER_IP',
80
+ 'ips ' => '127.0.0.1',
79
81
],
80
82
[
81
83
'path' => '^/admin',
82
- 'role ' => 'ROLE_USER_PORT',
84
+ 'roles ' => 'ROLE_USER_PORT',
83
85
'ip' => '127.0.0.1',
84
86
'port' => '8080',
85
87
],
86
88
[
87
89
'path' => '^/admin',
88
- 'role ' => 'ROLE_USER_HOST',
90
+ 'rolse ' => 'ROLE_USER_HOST',
89
91
'host' => 'symfony\.com$',
90
92
],
91
93
[
92
94
'path' => '^/admin',
93
- 'role ' => 'ROLE_USER_METHOD',
95
+ 'roles ' => 'ROLE_USER_METHOD',
94
96
'methods' => 'POST, PUT',
95
97
],
96
98
[
97
99
'path' => '^/admin',
98
- 'role' => 'ROLE_USER',
100
+ // when defining multiple roles, users must have at least one of them (it's like an OR condition)
101
+ 'roles' => ['ROLE_MANAGER', 'ROLE_ADMIN'],
99
102
],
100
103
],
101
104
]);
@@ -127,9 +130,10 @@ if ``ip``, ``port``, ``host`` or ``method`` are not specified for an entry, that
127
130
| ``/admin/user `` | 168.0.0.1 | 80 | example.com | POST | rule #4 (``ROLE_USER_METHOD ``) | The ``ip `` and ``host `` don't match the first two entries, |
128
131
| | | | | | | but the third - ``ROLE_USER_METHOD `` - matches and is used. |
129
132
+-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
130
- | ``/admin/user `` | 168.0.0.1 | 80 | example.com | GET | rule #5 (``ROLE_USER ``) | The ``ip ``, ``host `` and ``method `` prevent the first |
133
+ | ``/admin/user `` | 168.0.0.1 | 80 | example.com | GET | rule #4 (``ROLE_MANAGER ``) | The ``ip ``, ``host `` and ``method `` prevent the first |
131
134
| | | | | | | three entries from matching. But since the URI matches the |
132
- | | | | | | | ``path `` pattern of the ``ROLE_USER `` entry, it is used. |
135
+ | | | | | | | ``path `` pattern, then the ``ROLE_MANAGER `` (or the |
136
+ | | | | | | | ``ROLE_ADMIN ``) is used. |
133
137
+-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
134
138
| ``/foo `` | 127.0.0.1 | 80 | symfony.com | POST | matches no entries | This doesn't match any ``access_control `` rules, since its |
135
139
| | | | | | | URI doesn't match any of the ``path `` values. |
@@ -155,6 +159,14 @@ options:
155
159
does not match this value (e.g. ``https ``), the user will be redirected
156
160
(e.g. redirected from ``http `` to ``https ``, or vice versa).
157
161
162
+ .. tip ::
163
+
164
+ Behind the scenes, the array value of ``roles `` is passed as the
165
+ ``$attributes `` argument to each voter in the application with the
166
+ :class: `Symfony\\ Component\\ HttpFoundation\\ Request ` as ``$subject ``. You
167
+ can learn how to use your custom attributes by reading
168
+ :ref: `security/custom-voter `.
169
+
158
170
.. tip ::
159
171
160
172
If access is denied, the system will try to authenticate the user if not
@@ -191,8 +203,8 @@ pattern so that it is only accessible by requests from the local server itself:
191
203
access_control :
192
204
#
193
205
# the 'ips' option supports IP addresses and subnet masks
194
- - { path: ^/internal, roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1, 192.168.0.1/24] }
195
- - { path: ^/internal, roles: ROLE_NO_ACCESS }
206
+ - { path: ' ^/internal' , roles: IS_AUTHENTICATED_ANONYMOUSLY, ips: [127.0.0.1, ::1, 192.168.0.1/24] }
207
+ - { path: ' ^/internal' , roles: ROLE_NO_ACCESS }
196
208
197
209
.. code-block :: xml
198
210
@@ -225,13 +237,13 @@ pattern so that it is only accessible by requests from the local server itself:
225
237
'access_control' => [
226
238
[
227
239
'path' => '^/internal',
228
- 'role ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
240
+ 'roles ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
229
241
// the 'ips' option supports IP addresses and subnet masks
230
242
'ips' => ['127.0.0.1', '::1'],
231
243
],
232
244
[
233
245
'path' => '^/internal',
234
- 'role ' => 'ROLE_NO_ACCESS',
246
+ 'roles ' => 'ROLE_NO_ACCESS',
235
247
],
236
248
],
237
249
]);
@@ -276,7 +288,10 @@ key:
276
288
access_control :
277
289
-
278
290
path : ^/_internal/secure
279
- allow_if : " '127.0.0.1' == request.getClientIp() or is_granted('ROLE_ADMIN')"
291
+ # the 'role' and 'allow-if' options work like an OR expression, so
292
+ # access is granted if the expression is TRUE or the user has ROLE_ADMIN
293
+ roles : ' ROLE_ADMIN'
294
+ allow_if : " '127.0.0.1' == request.getClientIp() or request.header.has('X-Secure-Access')"
280
295
281
296
.. code-block :: xml
282
297
@@ -290,8 +305,11 @@ key:
290
305
291
306
<config >
292
307
<!-- ... -->
308
+ <!-- the 'role' and 'allow-if' options work like an OR expression, so
309
+ access is granted if the expression is TRUE or the user has ROLE_ADMIN -->
293
310
<rule path =" ^/_internal/secure"
294
- allow-if =" '127.0.0.1' == request.getClientIp() or is_granted('ROLE_ADMIN')" />
311
+ role =" ROLE_ADMIN"
312
+ allow-if =" '127.0.0.1' == request.getClientIp() or request.header.has('X-Secure-Access')" />
295
313
</config >
296
314
</srv : container >
297
315
@@ -303,14 +321,23 @@ key:
303
321
'access_control' => [
304
322
[
305
323
'path' => '^/_internal/secure',
306
- 'allow_if' => '"127.0.0.1" == request.getClientIp() or is_granted("ROLE_ADMIN")',
324
+ // the 'role' and 'allow-if' options work like an OR expression, so
325
+ // access is granted if the expression is TRUE or the user has ROLE_ADMIN
326
+ 'roles' => 'ROLE_ADMIN',
327
+ 'allow_if' => '"127.0.0.1" == request.getClientIp() or request.header.has('X-Secure-Access')',
307
328
],
308
329
],
309
330
]);
310
331
311
- In this case, when the user tries to access any URL starting with ``/_internal/secure ``,
312
- they will only be granted access if the IP address is ``127.0.0.1 `` or if
313
- the user has the ``ROLE_ADMIN `` role.
332
+ In this case, when the user tries to access any URL starting with
333
+ ``/_internal/secure ``, they will only be granted access if the IP address is
334
+ ``127.0.0.1 `` or a secure header, or if the user has the ``ROLE_ADMIN `` role.
335
+
336
+ .. note ::
337
+
338
+ Internally ``allow_if `` triggers the built-in
339
+ :class: `Symfony\\ Component\\ Security\\ Core\\ Authorization\\ Voter\\ ExpressionVoter `
340
+ as like it was part of the attributes defined in the ``roles `` option.
314
341
315
342
Inside the expression, you have access to a number of different variables
316
343
and functions including ``request ``, which is the Symfony
@@ -420,7 +447,7 @@ the user will be redirected to ``https``:
420
447
'access_control' => [
421
448
[
422
449
'path' => '^/cart/checkout',
423
- 'role ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
450
+ 'roles ' => 'IS_AUTHENTICATED_ANONYMOUSLY',
424
451
'requires_channel' => 'https',
425
452
],
426
453
],
0 commit comments