@@ -24,6 +24,7 @@ options are used for matching:
2424
2525* ``path ``
2626* ``ip `` or ``ips `` (netmasks are also supported)
27+ * ``port ``
2728* ``host ``
2829* ``methods ``
2930
@@ -38,6 +39,7 @@ Take the following ``access_control`` entries as an example:
3839 # ...
3940 access_control :
4041 - { path: ^/admin, roles: ROLE_USER_IP, ip: 127.0.0.1 }
42+ - { path: ^/admin, roles: ROLE_USER_IP, ip: 127.0.0.1, port: 8080 }
4143 - { path: ^/admin, roles: ROLE_USER_HOST, host: symfony\.com$ }
4244 - { path: ^/admin, roles: ROLE_USER_METHOD, methods: [POST, PUT] }
4345 - { path: ^/admin, roles: ROLE_USER }
@@ -55,6 +57,7 @@ Take the following ``access_control`` entries as an example:
5557 <config >
5658 <!-- ... -->
5759 <rule path =" ^/admin" role =" ROLE_USER_IP" ip =" 127.0.0.1" />
60+ <rule path =" ^/admin" role =" ROLE_USER_IP" ip =" 127.0.0.1" port =" 8080" />
5861 <rule path =" ^/admin" role =" ROLE_USER_HOST" host =" symfony\.com$" />
5962 <rule path =" ^/admin" role =" ROLE_USER_METHOD" methods =" POST, PUT" />
6063 <rule path =" ^/admin" role =" ROLE_USER" />
@@ -72,6 +75,12 @@ Take the following ``access_control`` entries as an example:
7275 'role' => 'ROLE_USER_IP',
7376 'ip' => '127.0.0.1',
7477 ),
78+ array(
79+ 'path' => '^/admin',
80+ 'role' => 'ROLE_USER_IP',
81+ 'ip' => '127.0.0.1',
82+ 'port' => '8080',
83+ ),
7584 array(
7685 'path' => '^/admin',
7786 'role' => 'ROLE_USER_HOST',
@@ -92,35 +101,37 @@ Take the following ``access_control`` entries as an example:
92101 For each incoming request, Symfony will decide which ``access_control ``
93102to use based on the URI, the client's IP address, the incoming host name,
94103and 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 ``:
97-
98- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
99- | URI | IP | HOST | METHOD | ``access_control `` | Why? |
100- +=================+=============+=============+============+================================+=============================================================+
101- | ``/admin/user `` | 127.0.0.1 | example.com | GET | rule #1 (``ROLE_USER_IP ``) | The URI matches ``path `` and the IP matches ``ip ``. |
102- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
103- | ``/admin/user `` | 127.0.0.1 | symfony.com | GET | rule #1 (``ROLE_USER_IP ``) | The ``path `` and ``ip `` still match. This would also match |
104- | | | | | | the ``ROLE_USER_HOST `` entry, but *only * the **first ** |
105- | | | | | | ``access_control `` match is used. |
106- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
107- | ``/admin/user `` | 168.0.0.1 | symfony.com | GET | rule #2 (``ROLE_USER_HOST ``) | The ``ip `` doesn't match the first rule, so the second |
108- | | | | | | rule (which matches) is used. |
109- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
110- | ``/admin/user `` | 168.0.0.1 | symfony.com | POST | rule #2 (``ROLE_USER_HOST ``) | The second rule still matches. This would also match the |
111- | | | | | | third rule (``ROLE_USER_METHOD ``), but only the **first ** |
112- | | | | | | matched ``access_control `` is used. |
113- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
114- | ``/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- | | | | | | but the third - ``ROLE_USER_METHOD `` - matches and is used. |
116- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
117- | ``/admin/user `` | 168.0.0.1 | example.com | GET | rule #4 (``ROLE_USER ``) | The ``ip ``, ``host `` and ``method `` prevent the first |
118- | | | | | | three entries from matching. But since the URI matches the |
119- | | | | | | ``path `` pattern of the ``ROLE_USER `` entry, it is used. |
120- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
121- | ``/foo `` | 127.0.0.1 | symfony.com | POST | matches no entries | This doesn't match any ``access_control `` rules, since its |
122- | | | | | | URI doesn't match any of the ``path `` values. |
123- +-----------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
104+ if ``ip ``, ``port ``, ``host `` or ``method `` are not specified for an entry, that ``access_control ``
105+ will match any ``ip ``, ``port ``, ``host `` or ``method ``:
106+
107+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
108+ | URI | IP | PORT | HOST | METHOD | ``access_control `` | Why? |
109+ +=================+=============+=============+=============+============+================================+=============================================================+
110+ | ``/admin/user `` | 127.0.0.1 | 80 | example.com | GET | rule #1 (``ROLE_USER_IP ``) | The URI matches ``path `` and the IP matches ``ip ``. |
111+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
112+ | ``/admin/user `` | 127.0.0.1 | 80 | symfony.com | GET | rule #1 (``ROLE_USER_IP ``) | The ``path `` and ``ip `` still match. This would also match |
113+ | | | | | | | the ``ROLE_USER_HOST `` entry, but *only * the **first ** |
114+ | | | | | | | ``access_control `` match is used. |
115+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
116+ | ``/admin/user `` | 127.0.0.1 | 8080 | symfony.com | GET | rule #2 (``ROLE_USER_PORT ``) | The ``path ``, ``ip `` and ``port `` match. |
117+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
118+ | ``/admin/user `` | 168.0.0.1 | 80 | symfony.com | GET | rule #3 (``ROLE_USER_HOST ``) | The ``ip `` doesn't match the first rule, so the second |
119+ | | | | | | | rule (which matches) is used. |
120+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
121+ | ``/admin/user `` | 168.0.0.1 | 80 | symfony.com | POST | rule #3 (``ROLE_USER_HOST ``) | The second rule still matches. This would also match the |
122+ | | | | | | | third rule (``ROLE_USER_METHOD ``), but only the **first ** |
123+ | | | | | | | matched ``access_control `` is used. |
124+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
125+ | ``/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, |
126+ | | | | | | | but the third - ``ROLE_USER_METHOD `` - matches and is used. |
127+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
128+ | ``/admin/user `` | 168.0.0.1 | 80 | example.com | GET | rule #5 (``ROLE_USER ``) | The ``ip ``, ``host `` and ``method `` prevent the first |
129+ | | | | | | | three entries from matching. But since the URI matches the |
130+ | | | | | | | ``path `` pattern of the ``ROLE_USER `` entry, it is used. |
131+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
132+ | ``/foo `` | 127.0.0.1 | 80 | symfony.com | POST | matches no entries | This doesn't match any ``access_control `` rules, since its |
133+ | | | | | | | URI doesn't match any of the ``path `` values. |
134+ +-----------------+-------------+-------------+-------------+------------+--------------------------------+-------------------------------------------------------------+
124135
125136.. _security-access-control-enforcement-options :
126137
@@ -167,6 +178,12 @@ requests *except* those from a trusted, internal server.
167178 and users accessing it from a different IP address will continue down
168179 the ``access_control `` list.
169180
181+ .. tip ::
182+
183+ You can add the option ``port `` to use only a specific port.
184+ It could be useful for ``localhost:8080 `` by example.
185+ See :ref: `Forcing a port <forcing-a-port >`
186+
170187Here is an example of how you configure some example ``/internal* `` URL
171188pattern so that it is only accessible by requests from the local server itself:
172189
@@ -313,6 +330,51 @@ For a list of the other functions and variables, see
313330 The feature to use custom functions inside ``allow_if `` expressions was
314331 introduced in Symfony 4.1.
315332
333+ Restrict to a port
334+ ------------------
335+
336+ You can also require a user to access a URL via a specific port; just use the
337+ ``port `` argument in any ``access_control `` entries.
338+
339+ .. configuration-block ::
340+
341+ .. code-block :: yaml
342+
343+ # config/packages/security.yaml
344+ security :
345+ # ...
346+ access_control :
347+ - { path: ^/cart/checkout, roles: IS_AUTHENTICATED_ANONYMOUSLY, port: 8080 }
348+
349+ .. code-block :: xml
350+
351+ <!-- config/packages/security.xml -->
352+ <?xml version =" 1.0" encoding =" UTF-8" ?>
353+ <srv : container xmlns =" http://symfony.com/schema/dic/security"
354+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
355+ xmlns : srv =" http://symfony.com/schema/dic/services"
356+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
357+ http://symfony.com/schema/dic/services/services-1.0.xsd" >
358+
359+ <rule path =" ^/cart/checkout"
360+ role =" IS_AUTHENTICATED_ANONYMOUSLY"
361+ port =" 8080"
362+ />
363+ </srv : container >
364+
365+ .. code-block :: php
366+
367+ // config/packages/security.php
368+ $container->loadFromExtension('security', array(
369+ 'access_control' => array(
370+ array(
371+ 'path' => '^/cart/checkout',
372+ 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY',
373+ 'port' => '8080',
374+ ),
375+ ),
376+ ));
377+
316378 Forcing a Channel (http, https)
317379-------------------------------
318380
0 commit comments