From 929ff6f98b65f7fdf092c855464f384445de6b20 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:20:02 +0200 Subject: [PATCH 1/8] =?UTF-8?q?SecurityEvents::INTERACTIVE=5FLOGIN=20?= =?UTF-8?q?=E2=86=92=20AuthenticationTokenCreatedEvent?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../in_memory/config/services.yaml | 2 +- ...=> AuthenticationTokenCreatedSubscriber.php} | 17 ++++++++--------- docs/users/user_authentication.md | 8 ++++---- 3 files changed, 13 insertions(+), 14 deletions(-) rename code_samples/user_management/in_memory/src/EventSubscriber/{InteractiveLoginSubscriber.php => AuthenticationTokenCreatedSubscriber.php} (65%) diff --git a/code_samples/user_management/in_memory/config/services.yaml b/code_samples/user_management/in_memory/config/services.yaml index 026797cd49..a95531ace9 100644 --- a/code_samples/user_management/in_memory/config/services.yaml +++ b/code_samples/user_management/in_memory/config/services.yaml @@ -1,5 +1,5 @@ services: - App\EventSubscriber\InteractiveLoginSubscriber: + App\EventSubscriber\AuthenticationTokenCreatedSubscriber: arguments: $userMap: from_memory_user: generic_customer diff --git a/code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php b/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php similarity index 65% rename from code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php rename to code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php index 3ce8af967d..20cba2bf4f 100644 --- a/code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php +++ b/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php @@ -8,10 +8,9 @@ use Ibexa\Core\MVC\Symfony\Security\UserWrapped; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Core\User\InMemoryUser; -use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; -use Symfony\Component\Security\Http\SecurityEvents; +use Symfony\Component\Security\Http\Event\AuthenticationTokenCreatedEvent; -final readonly class InteractiveLoginSubscriber implements EventSubscriberInterface +final readonly class AuthenticationTokenCreatedSubscriber implements EventSubscriberInterface { /** @param array $userMap */ public function __construct( @@ -24,17 +23,17 @@ public function __construct( public static function getSubscribedEvents(): array { return [ - SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin', + AuthenticationTokenCreatedEvent::class => ['onAuthenticationTokenCreated', 10], ]; } - public function onInteractiveLogin(InteractiveLoginEvent $event): void + public function onAuthenticationTokenCreated(AuthenticationTokenCreatedEvent $event): void { - $tokenUser = $event->getAuthenticationToken()->getUser(); + $tokenUser = $event->getAuthenticatedToken()->getUser(); if (!$tokenUser instanceof InMemoryUser) { return; } - $userIdentifier = $event->getAuthenticationToken()->getUserIdentifier(); + $userIdentifier = $event->getAuthenticatedToken()->getUserIdentifier(); $ibexaUser = null; if (array_key_exists($userIdentifier, $this->userMap)) { $ibexaUser = $this->userService->loadUserByLogin($this->userMap[$userIdentifier]); @@ -43,7 +42,7 @@ public function onInteractiveLogin(InteractiveLoginEvent $event): void $anonymousUserId = (int)$this->configResolver->getParameter('anonymous_user_id'); $ibexaUser = $this->userService->loadUser($anonymousUserId); } - //$event->getAuthenticationToken()->setUser(new User($ibexaUser)); - $event->getAuthenticationToken()->setUser(new UserWrapped($tokenUser, $ibexaUser)); + //$event->getAuthenticatedToken()->setUser(new User($ibexaUser)); + $event->getAuthenticatedToken()->setUser(new UserWrapped($tokenUser, $ibexaUser)); } } diff --git a/docs/users/user_authentication.md b/docs/users/user_authentication.md index f69d7c02d2..cf71300954 100644 --- a/docs/users/user_authentication.md +++ b/docs/users/user_authentication.md @@ -14,8 +14,8 @@ This is mainly for the kernel to be able to manage content-related permissions ( Depending on your context, you either want to create and return an Ibexa user, or return an existing user, even a generic one. -Whenever a user is matched, Symfony initiates a `SecurityEvents::INTERACTIVE_LOGIN` event. -Every service listening to this event receives an `InteractiveLoginEvent` object which contains the original security token (that holds the matched user) and the request. +Whenever a user is matched, Symfony initiates an `AuthenticationTokenCreatedEvent` event during authentication. +Every service listening to this event receives an object which contains the original security token (that holds the matched user) and a [passport]([[= symfony_doc =]]/security/custom_authenticator.html#security-passports). Then, it's up to a listener to retrieve an Ibexa user from the repository. @@ -32,11 +32,11 @@ The following example uses the [memory user provider]([[= symfony_doc =]]/securi maps memory user to Ibexa repository user, and [chains]([[= symfony_doc =]]/security/user_providers.html#chain-user-provider) with the Ibexa user provider to be able to use both: -Create as `src/EventSubscriber/InteractiveLoginSubscriber.php` subscribing to the `SecurityEvents::INTERACTIVE_LOGIN` event +Create as `src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php` subscribing to the `AuthenticationTokenCreatedEvent` event and mapping when needed an in-memory authenticated user to an Ibexa user: ``` php -[[= include_file('code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php') =]] +[[= include_file('code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php') =]] ``` In `config/packages/security.yaml`, From 152729f5361ea9cf47e52f9e29bfe4adacdef6b2 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:51:36 +0200 Subject: [PATCH 2/8] Fix deptrac --- deptrac.baseline.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/deptrac.baseline.yaml b/deptrac.baseline.yaml index e41e6332fe..9fef31d4bc 100644 --- a/deptrac.baseline.yaml +++ b/deptrac.baseline.yaml @@ -120,6 +120,8 @@ deptrac: App\EventListener\TextAnchorMenuTabListener: - Ibexa\AdminUi\Menu\ContentEditAnchorMenuBuilder - Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent + App\EventSubscriber\AuthenticationTokenCreatedSubscriber: + - Ibexa\Core\MVC\Symfony\Security\UserWrapped App\EventSubscriber\BreadcrumbsMenuSubscriber: - Ibexa\Bundle\Storefront\Menu\Builder\BreadcrumbsMenuBuilder App\EventSubscriber\FormFieldDefinitionSubscriber: @@ -128,8 +130,6 @@ deptrac: - Ibexa\FormBuilder\Event\FormEvents App\EventSubscriber\HelpMenuSubscriber: - Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent - App\EventSubscriber\InteractiveLoginSubscriber: - - Ibexa\Core\MVC\Symfony\Security\User App\EventSubscriber\MyMenuSubscriber: - Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent - Ibexa\AdminUi\Menu\MainMenuBuilder From d7de84ea542badf105e2c2e4eb69d448bbc4399d Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Mon, 8 Jun 2026 17:55:11 +0200 Subject: [PATCH 3/8] Fix deptrac --- deptrac.baseline.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/deptrac.baseline.yaml b/deptrac.baseline.yaml index 9fef31d4bc..14b0c9e538 100644 --- a/deptrac.baseline.yaml +++ b/deptrac.baseline.yaml @@ -121,6 +121,7 @@ deptrac: - Ibexa\AdminUi\Menu\ContentEditAnchorMenuBuilder - Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent App\EventSubscriber\AuthenticationTokenCreatedSubscriber: + #- Ibexa\Core\MVC\Symfony\Security\User - Ibexa\Core\MVC\Symfony\Security\UserWrapped App\EventSubscriber\BreadcrumbsMenuSubscriber: - Ibexa\Bundle\Storefront\Menu\Builder\BreadcrumbsMenuBuilder From 2e39549696f0fb90cc5caf06330286b2d80c0bdb Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 9 Jun 2026 09:27:49 +0200 Subject: [PATCH 4/8] Apply suggestion from @adriendupuis --- docs/users/user_authentication.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/users/user_authentication.md b/docs/users/user_authentication.md index cf71300954..96ac9d92cd 100644 --- a/docs/users/user_authentication.md +++ b/docs/users/user_authentication.md @@ -14,7 +14,7 @@ This is mainly for the kernel to be able to manage content-related permissions ( Depending on your context, you either want to create and return an Ibexa user, or return an existing user, even a generic one. -Whenever a user is matched, Symfony initiates an `AuthenticationTokenCreatedEvent` event during authentication. +Whenever a user is matched and authenticated, Symfony initiates an `AuthenticationTokenCreatedEvent`. Every service listening to this event receives an object which contains the original security token (that holds the matched user) and a [passport]([[= symfony_doc =]]/security/custom_authenticator.html#security-passports). Then, it's up to a listener to retrieve an Ibexa user from the repository. From f3f7786917ecaeb53b38b19afe5369bdcc95aa56 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 9 Jun 2026 09:37:40 +0200 Subject: [PATCH 5/8] AuthenticationTokenCreatedSubscriber: facto, clean-up --- .../AuthenticationTokenCreatedSubscriber.php | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php b/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php index 20cba2bf4f..41d5c6a580 100644 --- a/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php +++ b/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php @@ -4,7 +4,6 @@ use Ibexa\Contracts\Core\Repository\UserService; use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface; -//use Ibexa\Core\MVC\Symfony\Security\User; use Ibexa\Core\MVC\Symfony\Security\UserWrapped; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Core\User\InMemoryUser; @@ -29,11 +28,12 @@ public static function getSubscribedEvents(): array public function onAuthenticationTokenCreated(AuthenticationTokenCreatedEvent $event): void { - $tokenUser = $event->getAuthenticatedToken()->getUser(); + $token = $event->getAuthenticatedToken(); + $tokenUser = $token->getUser(); if (!$tokenUser instanceof InMemoryUser) { return; } - $userIdentifier = $event->getAuthenticatedToken()->getUserIdentifier(); + $userIdentifier = $token->getUserIdentifier(); $ibexaUser = null; if (array_key_exists($userIdentifier, $this->userMap)) { $ibexaUser = $this->userService->loadUserByLogin($this->userMap[$userIdentifier]); @@ -42,7 +42,6 @@ public function onAuthenticationTokenCreated(AuthenticationTokenCreatedEvent $ev $anonymousUserId = (int)$this->configResolver->getParameter('anonymous_user_id'); $ibexaUser = $this->userService->loadUser($anonymousUserId); } - //$event->getAuthenticatedToken()->setUser(new User($ibexaUser)); - $event->getAuthenticatedToken()->setUser(new UserWrapped($tokenUser, $ibexaUser)); + $token->setUser(new UserWrapped($tokenUser, $ibexaUser)); } } From 32693c6ad2d4cdfc56e12c4eb242cbcdb573e2ee Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 9 Jun 2026 09:38:44 +0200 Subject: [PATCH 6/8] Apply suggestion from @adriendupuis --- deptrac.baseline.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/deptrac.baseline.yaml b/deptrac.baseline.yaml index 14b0c9e538..9fef31d4bc 100644 --- a/deptrac.baseline.yaml +++ b/deptrac.baseline.yaml @@ -121,7 +121,6 @@ deptrac: - Ibexa\AdminUi\Menu\ContentEditAnchorMenuBuilder - Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent App\EventSubscriber\AuthenticationTokenCreatedSubscriber: - #- Ibexa\Core\MVC\Symfony\Security\User - Ibexa\Core\MVC\Symfony\Security\UserWrapped App\EventSubscriber\BreadcrumbsMenuSubscriber: - Ibexa\Bundle\Storefront\Menu\Builder\BreadcrumbsMenuBuilder From 1d35a779a46eefe744b56e61251d0c2ecdfe0fae Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 9 Jun 2026 10:25:48 +0200 Subject: [PATCH 7/8] AuthenticationTokenCreatedSubscriber: increase priority --- .../EventSubscriber/AuthenticationTokenCreatedSubscriber.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php b/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php index 41d5c6a580..4f351028c5 100644 --- a/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php +++ b/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php @@ -22,7 +22,7 @@ public function __construct( public static function getSubscribedEvents(): array { return [ - AuthenticationTokenCreatedEvent::class => ['onAuthenticationTokenCreated', 10], + AuthenticationTokenCreatedEvent::class => ['onAuthenticationTokenCreated', 11], ]; } From 1f7e81c01970352c4efa1719596afe91c20eddcb Mon Sep 17 00:00:00 2001 From: Adrien Dupuis <61695653+adriendupuis@users.noreply.github.com> Date: Tue, 9 Jun 2026 10:38:38 +0200 Subject: [PATCH 8/8] user_authentication.md: about priority --- docs/users/user_authentication.md | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/docs/users/user_authentication.md b/docs/users/user_authentication.md index 96ac9d92cd..8d24b4aa41 100644 --- a/docs/users/user_authentication.md +++ b/docs/users/user_authentication.md @@ -24,7 +24,7 @@ This Ibexa user can be - embedded into `Ibexa\Core\MVC\Symfony\Security\User` while forgetting about the original user - wrapped into `Ibexa\Core\MVC\Symfony\Security\UserWrapped` with the original user if needed -Finally, this user is assigned back into the event's token for the rest of the request. +Finally, this user is assigned back into the event's token for the rest of the process. ### User mapping example @@ -56,9 +56,19 @@ In the `config/services.yaml` file, declare the subscriber as a service to pass [[= include_file('code_samples/user_management/in_memory/config/services.yaml') =]] ``` +You can list the subscribers with the following command to check their order: + +``` bash +php bin/console debug:event-dispatcher AuthenticationTokenCreatedEvent +``` + +Notice that the example subscriber priority is `11` so it's executed before +the `Ibexa\Core\MVC\Symfony\Security\Authentication\EventSubscriber\OnAuthenticationTokenCreatedRepositoryUserSubscriber` +which set the Ibexa user as the current user. + From the back office, create the mapped users. For the example, a new user with the login `generic_customer` and a random password for the mapping to work, this account can be in the **Customers** or the **Anonymous users** group. -You can now log in with a in-memory user. +You can now log in with an in-memory user. In the Symfony debug toolbar, you should see the in-memory user as this example uses `UserWrapped`.