Skip to content

Update "User authentication" customization example (5.0)#3087

Open
adriendupuis wants to merge 9 commits into5.0from
user_auth_5.0
Open

Update "User authentication" customization example (5.0)#3087
adriendupuis wants to merge 9 commits into5.0from
user_auth_5.0

Conversation

@adriendupuis
Copy link
Contributor

@adriendupuis adriendupuis commented Mar 13, 2026

Question Answer
JIRA Ticket IBX-11465
Versions 5.0
Edition All

Checklist

  • Text renders correctly
  • Text has been checked with vale
  • Description metadata is up to date
  • Redirects cover removed/moved pages
  • Code samples are working
  • PHP code samples have been fixed with PHP CS fixer
  • Added link to this PR in relevant JIRA ticket or code PR

@github-actions
Copy link

Preview of modified files

Preview of modified Markdown:

@sonarqubecloud
Copy link

@github-actions
Copy link

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/user_management/in_memory/config/packages/security.yaml


code_samples/user_management/in_memory/config/packages/security.yaml

docs/users/user_authentication.md@42:``` yaml
docs/users/user_authentication.md@43:[[= include_file('code_samples/user_management/in_memory/config/packages/security.yaml') =]]
docs/users/user_authentication.md@44:```

001⫶security:
002⫶ password_hashers:
003⫶ # The in-memory provider requires an encoder
004⫶ Symfony\Component\Security\Core\User\InMemoryUser: plaintext
005⫶ Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
006⫶
007⫶ # https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
008⫶ providers:
009⫶ in_memory:
010⫶ memory:
011⫶ users:
012⫶ from_memory_user: { password: from_memory_pass, roles: [ 'ROLE_USER' ] }
013⫶ from_memory_admin: { password: from_memory_publish, roles: [ 'ROLE_USER' ] }
014⫶ ibexa:
015⫶ id: ibexa.security.user_provider
016⫶ # Chaining in_memory and ibexa user providers
017⫶ chained:
018⫶ chain:
019⫶ providers: [ in_memory, ibexa ]
020⫶
021⫶ firewalls:
022⫶ # …
023⫶ ibexa_front:
024⫶ pattern: ^/
025⫶ provider: chained
026⫶ user_checker: Ibexa\Core\MVC\Symfony\Security\UserChecker
027⫶ context: ibexa
028⫶ form_login:
029⫶ enable_csrf: true
030⫶ login_path: login
031⫶ check_path: login_check
032⫶ custom_authenticators:
033⫶ - Ibexa\PageBuilder\Security\EditorialMode\FragmentAuthenticator
034⫶ entry_point: form_login
035⫶ logout:
036⫶ path: logout


code_samples/user_management/in_memory/config/services.yaml


code_samples/user_management/in_memory/config/services.yaml

docs/users/user_authentication.md@49:``` yaml
docs/users/user_authentication.md@50:[[= include_file('code_samples/user_management/in_memory/config/services.yaml') =]]
docs/users/user_authentication.md@51:```

001⫶App\EventSubscriber\InteractiveLoginSubscriber:
002⫶ arguments:
003⫶ $userMap:
004⫶ from_memory_user: customer
005⫶ from_memory_admin: admin


code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php


code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php

docs/users/user_authentication.md@32:``` php
docs/users/user_authentication.md@33:[[= include_file('code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php') =]]
docs/users/user_authentication.md@34:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\EventSubscriber;
004⫶
005⫶use Ibexa\Contracts\Core\Repository\UserService;
006⫶use Ibexa\Core\MVC\Symfony\Security\User;
007⫶use Symfony\Component\EventDispatcher\EventSubscriberInterface;
008⫶use Symfony\Component\Security\Core\User\InMemoryUser;
009⫶use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
010⫶use Symfony\Component\Security\Http\SecurityEvents;
011⫶
012⫶class InteractiveLoginSubscriber implements EventSubscriberInterface
013⫶{
014⫶ /** @param array<string, string> $userMap */
015⫶ public function __construct(
016⫶ private readonly UserService $userService,
017⫶ private readonly array $userMap = [],
018⫶ ) {
019⫶ }
020⫶
021⫶ public static function getSubscribedEvents()
022⫶ {
023⫶ return [
024⫶ SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin',
025⫶ ];
026⫶ }
027⫶
028⫶ public function onInteractiveLogin(InteractiveLoginEvent $event): InteractiveLoginEvent
029⫶ {
030⫶ $tokenUser = $event->getAuthenticationToken()->getUser();
031⫶ if ($tokenUser instanceof InMemoryUser) {
032⫶ $userLogin = $this->userMap[$event->getAuthenticationToken()->getUserIdentifier()] ?? 'anonymous';
033⫶ $ibexaUser = $this->userService->loadUserByLogin($userLogin);
034⫶ $event->getAuthenticationToken()->setUser(new User($ibexaUser));
035⫶ }
036⫶
037⫶ return $event;
038⫶ }
039⫶}

Download colorized diff

Comment on lines +33 to +34
$ibexaUser = $this->userService->loadUserByLogin($userLogin);
$event->getAuthenticationToken()->setUser(new User($ibexaUser));
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could use Ibexa\Core\MVC\Symfony\Security\User\UsernameProvider::loadUserByIdentifier() to get the repo user already wrapped:

Suggested change
$ibexaUser = $this->userService->loadUserByLogin($userLogin);
$event->getAuthenticationToken()->setUser(new User($ibexaUser));
$ibexaUser = $this->userNameProvider->loadUserByIdentifier($userLogin);
$event->getAuthenticationToken()->setUser($ibexaUser);

but it's still out of Contracts namespace.

@adriendupuis adriendupuis marked this pull request as ready for review March 13, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant