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 63% 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..4f351028c5 100644 --- a/code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php +++ b/code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php @@ -4,14 +4,12 @@ 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; -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 +22,18 @@ public function __construct( public static function getSubscribedEvents(): array { return [ - SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin', + AuthenticationTokenCreatedEvent::class => ['onAuthenticationTokenCreated', 11], ]; } - public function onInteractiveLogin(InteractiveLoginEvent $event): void + public function onAuthenticationTokenCreated(AuthenticationTokenCreatedEvent $event): void { - $tokenUser = $event->getAuthenticationToken()->getUser(); + $token = $event->getAuthenticatedToken(); + $tokenUser = $token->getUser(); if (!$tokenUser instanceof InMemoryUser) { return; } - $userIdentifier = $event->getAuthenticationToken()->getUserIdentifier(); + $userIdentifier = $token->getUserIdentifier(); $ibexaUser = null; if (array_key_exists($userIdentifier, $this->userMap)) { $ibexaUser = $this->userService->loadUserByLogin($this->userMap[$userIdentifier]); @@ -43,7 +42,6 @@ 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)); + $token->setUser(new UserWrapped($tokenUser, $ibexaUser)); } } diff --git a/deptrac.baseline.yaml b/deptrac.baseline.yaml index 2fbb924b9d..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,9 +130,6 @@ deptrac: - Ibexa\FormBuilder\Event\FormEvents App\EventSubscriber\HelpMenuSubscriber: - Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent - App\EventSubscriber\InteractiveLoginSubscriber: - #- Ibexa\Core\MVC\Symfony\Security\User - - Ibexa\Core\MVC\Symfony\Security\UserWrapped App\EventSubscriber\MyMenuSubscriber: - Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent - Ibexa\AdminUi\Menu\MainMenuBuilder diff --git a/docs/users/user_authentication.md b/docs/users/user_authentication.md index f69d7c02d2..8d24b4aa41 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 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. @@ -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 @@ -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`, @@ -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`.