Files
archived-symfony-docs/security/force_https.rst
Javier Eguiluz d554037f9a Merge branch '5.4' into 6.3
* 5.4:
  [Security] Improve `requires_channel` var naming
2023-10-04 09:08:46 +02:00

93 lines
3.4 KiB
ReStructuredText

How to Force HTTPS or HTTP for different URLs
=============================================
.. tip::
The *best* policy is to force ``https`` on all URLs, which can be done via
your web server configuration or ``access_control``.
You can force areas of your site to use the HTTPS protocol in the security
config. This is done through the ``access_control`` rules using the ``requires_channel``
option. To enforce HTTPS on all URLs, add the ``requires_channel`` config to every
access control:
.. configuration-block::
.. code-block:: yaml
# config/packages/security.yaml
security:
# ...
access_control:
- { path: '^/secure', roles: ROLE_ADMIN, requires_channel: https }
- { path: '^/login', roles: PUBLIC_ACCESS, requires_channel: https }
# catch all other URLs
- { path: '^/', roles: PUBLIC_ACCESS, requires_channel: https }
.. code-block:: xml
<!-- config/packages/security.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services
https://symfony.com/schema/dic/services/services-1.0.xsd
http://symfony.com/schema/dic/security
https://symfony.com/schema/dic/security/security-1.0.xsd">
<config>
<!-- ... -->
<rule path="^/secure" role="ROLE_ADMIN" requires-channel="https"/>
<rule path="^/login" role="PUBLIC_ACCESS" requires-channel="https"/>
<rule path="^/" role="PUBLIC_ACCESS" requires-channel="https"/>
</config>
</srv:container>
.. code-block:: php
// config/packages/security.php
use Symfony\Config\SecurityConfig;
return static function (SecurityConfig $security): void {
// ....
$security->accessControl()
->path('^/secure')
->roles(['ROLE_ADMIN'])
->requiresChannel('https')
;
$security->accessControl()
->path('^/login')
->roles(['PUBLIC_ACCESS'])
->requiresChannel('https')
;
$security->accessControl()
->path('^/')
->roles(['PUBLIC_ACCESS'])
->requiresChannel('https')
;
};
To make life easier while developing, you can also use an environment variable,
like ``requires_channel: '%env(REQUIRED_SCHEME)%'``. In your ``.env`` file, set
``REQUIRED_SCHEME`` to ``http`` by default, but override it to ``https`` on production.
See :doc:`/security/access_control` for more details about ``access_control``
in general.
.. note::
An alternative way to enforce HTTP or HTTPS is to use
:ref:`the scheme option <routing-force-https>` of a route or group of routes.
.. note::
Forcing HTTPS while using a reverse proxy or load balancer requires a proper
configuration to avoid infinite redirect loops; see :doc:`/deployment/proxies`
for more details.