44Security
55========
66
7+
78Symfony provides many tools to secure your application. Some HTTP-related
89security tools, like:doc: `secure session cookies </session >` and
910:doc: `CSRF protection </security/csrf >` are provided by default. The
@@ -73,6 +74,15 @@ discussed:
7374 required permissions to perform a specific action or visit a specific
7475 URL.
7576
77+ ..caution ::
78+
79+ Symfony Security has received major changes in 5.3. This article
80+ explains the *new authenticator-based * system (identified by the
81+ ``enable_authenticator_manager: true `` config option).
82+
83+ Refer to the `5.2 version of this documentation `_ if you're still using
84+ the legacy security system.
85+
7686.. _create-user-class :
7787.. _a-create-your-user-class :
7888
@@ -645,6 +655,8 @@ many other authenticators:
645655 Google, Facebook or Twitter (social login), check out the `HWIOAuthBundle `_
646656 community bundle.
647657
658+ .. _security-form-login :
659+
648660Form Login
649661~~~~~~~~~~
650662
@@ -780,7 +792,7 @@ If the user submits an invalid email or password, that authenticator will store
780792the error and redirect back to this controller, where we read the error (using
781793``AuthenticationUtils ``) so that it can be displayed back to the user.
782794
783- Finally, create orupdaate the template:
795+ Finally, create orupdate the template:
784796
785797..code-block ::html+twig
786798
@@ -851,6 +863,11 @@ To review the whole process:
851863 request, checks the user's submitted credentials, authenticates the user if
852864 they are correct, and sends the user back to the login form if they are not.
853865
866+ ..seealso ::
867+
868+ You can customize the responses on a successful or failed login
869+ attempt. See:doc: `/security/form_login `.
870+
854871.. _form_login-csrf :
855872
856873CSRF Protection in Login Forms
@@ -1051,8 +1068,14 @@ token (or whatever you need to return) and return the JSON response:
10511068 {
10521069 #[Route('/api/login', name: 'api_login')]
10531070 - public function index(): Response
1054- + public function index(#[CurrentUser] User $user): Response
1071+ + public function index(#[CurrentUser]? User $user): Response
10551072 {
1073+ + if (null === $user) {
1074+ + return $this->json([
1075+ + 'message' => 'missing credentials',
1076+ + ], Response::HTTP_UNAUTHENTICATED);
1077+ + }
1078+ +
10561079 + $token = ...; // somehow create an API token for $user
10571080 +
10581081 return $this->json([
@@ -1764,67 +1787,6 @@ event class:
17641787 Returns a response, if it is already set by a custom listener. Use
17651788 ``setResponse() `` to configure a custom logout response.
17661789
1767- ..tip ::
1768-
1769- Every Security firewall has its own event dispatcher
1770- (``security.event_dispatcher.FIREWALLNAME ``). The logout event is
1771- dispatched on both the global and firewall dispatcher. You can register
1772- on the firewall dispatcher if you want your listener to only be
1773- called for a specific firewall. For instance, if you have an ``api ``
1774- and ``main `` firewall, use this configuration to register only on the
1775- logout event in the ``main `` firewall:
1776-
1777- ..configuration-block ::
1778-
1779- ..code-block ::yaml
1780-
1781- # config/services.yaml
1782- services :
1783- # ...
1784-
1785- App\EventListener\CustomLogoutSubscriber :
1786- tags :
1787- -name :kernel.event_subscriber
1788- dispatcher :security.event_dispatcher.main
1789-
1790- ..code-block ::xml
1791-
1792- <!-- config/services.xml-->
1793- <?xml version =" 1.0" encoding =" UTF-8" ?>
1794- <container xmlns =" http://symfony.com/schema/dic/services"
1795- xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
1796- xsi : schemaLocation =" http://symfony.com/schema/dic/services
1797- https://symfony.com/schema/dic/services/services-1.0.xsd" >
1798-
1799- <services >
1800- <!-- ...-->
1801-
1802- <service id =" App\EventListener\CustomLogoutSubscriber" >
1803- <tag name =" kernel.event_subscriber"
1804- dispacher =" security.event_dispatcher.main"
1805- />
1806- </service >
1807- </services >
1808- </container >
1809-
1810- ..code-block ::php
1811-
1812- // config/services.php
1813- namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1814-
1815- use App\EventListener\CustomLogoutListener;
1816- use App\EventListener\CustomLogoutSubscriber;
1817- use Symfony\Component\Security\Http\Event\LogoutEvent;
1818-
1819- return function(ContainerConfigurator $configurator) {
1820- $services = $configurator->services();
1821-
1822- $services->set(CustomLogoutSubscriber::class)
1823- ->tag('kernel.event_subscriber', [
1824- 'dispatcher' => 'security.event_dispatcher.main',
1825- ]);
1826- };
1827-
18281790.. _retrieving-the-user-object :
18291791
18301792Fetching the User Object
@@ -2406,10 +2368,6 @@ the login page):
24062368 Granting Anonymous Users Access in a Custom Voter
24072369~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
24082370
2409- ..versionadded ::5.2
2410-
2411- The ``NullToken `` class was introduced in Symfony 5.2.
2412-
24132371If you're using a:doc: `custom voter </security/voters >`, you can allow
24142372anonymous users access by checking if there is no user set on the token::
24152373
@@ -2480,12 +2438,6 @@ like this:
24802438 but stronger. Users who are logged in only because of a "remember me cookie"
24812439 will have ``IS_AUTHENTICATED_REMEMBERED `` but will not have ``IS_AUTHENTICATED_FULLY ``.
24822440
2483- * ``IS_AUTHENTICATED_ANONYMOUSLY ``: *All * users (even anonymous ones) have
2484- this - this is useful when defining a list of URLs with no access restriction
2485- - some details are in:doc: `/security/access_control `.
2486-
2487- * ``IS_ANONYMOUS ``: *Only * anonymous users are matched by this attribute.
2488-
24892441* ``IS_REMEMBERED ``: *Only * users authenticated using the
24902442:doc: `remember me functionality </security/remember_me >`, (i.e. a
24912443 remember-me cookie).
@@ -2496,8 +2448,13 @@ like this:
24962448
24972449..versionadded ::5.1
24982450
2499- The ``IS_ANONYMOUS ``, ``IS_REMEMBERED `` and ``IS_IMPERSONATOR ``
2500- attributes were introduced in Symfony 5.1.
2451+ The ``IS_REMEMBERED `` and ``IS_IMPERSONATOR `` attributes were
2452+ introduced in Symfony 5.1.
2453+
2454+ ..deprecated ::5.3
2455+
2456+ The ``IS_ANONYMOUS `` and ``IS_AUTHENTICATED_ANONYMOUSLY `` attributes are
2457+ deprecated since Symfony 5.3.
25012458
25022459.. _user_session_refresh :
25032460
@@ -2540,6 +2497,67 @@ to hook into the process or customize the response sent back to the user. You
25402497can do this by creating an:doc: `event listener or subscriber </event_dispatcher >`
25412498for these events.
25422499
2500+ ..tip ::
2501+
2502+ Every Security firewall has its own event dispatcher
2503+ (``security.event_dispatcher.FIREWALLNAME ``). Events are dispatched on
2504+ both the global and the firewall-specific dispatcher. You can register
2505+ on the firewall dispatcher if you want your listener to only be
2506+ called for a specific firewall. For instance, if you have an ``api ``
2507+ and ``main `` firewall, use this configuration to register only on the
2508+ logout event in the ``main `` firewall:
2509+
2510+ ..configuration-block ::
2511+
2512+ ..code-block ::yaml
2513+
2514+ # config/services.yaml
2515+ services :
2516+ # ...
2517+
2518+ App\EventListener\CustomLogoutSubscriber :
2519+ tags :
2520+ -name :kernel.event_subscriber
2521+ dispatcher :security.event_dispatcher.main
2522+
2523+ ..code-block ::xml
2524+
2525+ <!-- config/services.xml-->
2526+ <?xml version =" 1.0" encoding =" UTF-8" ?>
2527+ <container xmlns =" http://symfony.com/schema/dic/services"
2528+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
2529+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
2530+ https://symfony.com/schema/dic/services/services-1.0.xsd" >
2531+
2532+ <services >
2533+ <!-- ...-->
2534+
2535+ <service id =" App\EventListener\CustomLogoutSubscriber" >
2536+ <tag name =" kernel.event_subscriber"
2537+ dispacher =" security.event_dispatcher.main"
2538+ />
2539+ </service >
2540+ </services >
2541+ </container >
2542+
2543+ ..code-block ::php
2544+
2545+ // config/services.php
2546+ namespace Symfony\Component\DependencyInjection\Loader\Configurator;
2547+
2548+ use App\EventListener\CustomLogoutListener;
2549+ use App\EventListener\CustomLogoutSubscriber;
2550+ use Symfony\Component\Security\Http\Event\LogoutEvent;
2551+
2552+ return function(ContainerConfigurator $configurator) {
2553+ $services = $configurator->services();
2554+
2555+ $services->set(CustomLogoutSubscriber::class)
2556+ ->tag('kernel.event_subscriber', [
2557+ 'dispatcher' => 'security.event_dispatcher.main',
2558+ ]);
2559+ };
2560+
25432561 Authentication Events
25442562~~~~~~~~~~~~~~~~~~~~~
25452563
@@ -2576,7 +2594,7 @@ Other Events
25762594~~~~~~~~~~~~
25772595
25782596:class: `Symfony\\ Component\\ Security\\ Http\\ Event\\ LogoutEvent `
2579- Dispatchedwhen a user logs out of your application. See
2597+ Dispatchedjust before a user logs out of your application. See
25802598:ref: `security-logging-out `.
25812599
25822600:class: `Symfony\\ Component\\ Security\\ Http\\ Event\\ TokenDeauthenticatedEvent `
@@ -2640,6 +2658,7 @@ Authentication (Identifying/Logging in the User)
26402658security/csrf
26412659security/form_login
26422660security/custom_authenticator
2661+ security/entry_point
26432662
26442663Authorization (Denying Access)
26452664~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -2652,6 +2671,7 @@ Authorization (Denying Access)
26522671security/access_denied_handler
26532672security/force_https
26542673
2674+ .. _`5.2 version of this documentation` :https://symfony.com/doc/5.2/security.html
26552675.. _`FrameworkExtraBundle documentation` :https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html
26562676.. _`HWIOAuthBundle` :https://github.com/hwi/HWIOAuthBundle
26572677.. _`OWASP Brute Force Attacks` :https://owasp.org/www-community/controls/Blocking_Brute_Force_Attacks