Skip to main content
Version: Next

External Authentication Services

The portal engine provides several events to make it possible to integrate external authentication services via the login form.

  • Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginCheckPasswordEvent
  • Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginFieldTypeEvent
  • Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginGetUsserEvent
  • Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginPasswordChangeableEvent

Important: It is needed to create a PortalUser data object for all external users too to make the portal engine work correctly.

Example​

This example event subscriber will allow Pimcore admin users to login to the portal engine as admin users too.

<?php

namespace AppBundle\EventListener;

use Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginCheckPasswordEvent;
use Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginFieldTypeEvent;
use Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginGetUserEvent;
use Pimcore\Bundle\PortalEngineBundle\Event\Auth\LoginPasswordChangeableEvent;
use Pimcore\Model\DataObject\PortalUser;
use Pimcore\Model\DataObject\Service;
use Pimcore\Model\User;
use Pimcore\Tool\Authentication;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class PortalEngineAuthenticationSubscriber implements EventSubscriberInterface
{
const USER_FOLDER = '/Portal Engine/Users/Pimcore';

public static function getSubscribedEvents()
{
return [
LoginFieldTypeEvent::class => 'onLoginFieldType',
LoginGetUserEvent::class => 'onLoginGetUser',
LoginCheckPasswordEvent::class => 'onLoginCheckPassword',
LoginPasswordChangeableEvent::class => 'onPasswordChangeable',
];
}

public function onLoginFieldType(LoginFieldTypeEvent $event)
{
//switch the login form to allow non-email user names
$event->setUseEmailField(false);
}

public function onLoginGetUser(LoginGetUserEvent $event)
{
$portalUser = null;
$pimcoreUser = User::getByName($event->getUserName());
if ($pimcoreUser && $pimcoreUser->getAdmin()) {
$portalUser = $this->getOrCreatePortalUserByPimcoreUser($pimcoreUser);
$event->setPortalUser($portalUser);
}
}

public function onLoginCheckPassword(LoginCheckPasswordEvent $event)
{
$portalUser = $event->getPortalUser();
if ($portalUser->getExternalUserId()) {
$pimcoreUser = User::getByName($portalUser->getExternalUserId());
$success = Authentication::isValidUser($pimcoreUser)
&& Authentication::verifyPassword(
$pimcoreUser,
$event->getPassword()
);

if ($success) {
$event->setLoginValid(true);
}
}
}

public function onPasswordChangeable(LoginPasswordChangeableEvent $event)
{
/* If an external authentication service is used it might be needed to disable
* the recover/change password functionality.
*
* In this example this is not necessary.
*/

//$event->setPasswordChangeable(false);
}

protected function getOrCreatePortalUserByPimcoreUser(User $pimcoreUser)
{
// to make the portal engine work it is needed to create a portal user data object
$portalUser = PortalUser::getByExternalUserId($pimcoreUser->getName(), 1);
if (empty($portalUser)) {
$portalUser = new PortalUser();
$portalUser->setPimcoreUser($pimcoreUser->getId())
->setExternalUserId($pimcoreUser->getName())
->setAdmin(true)
->setKey($pimcoreUser->getName())
->setEmail($pimcoreUser->getEmail())
->setFirstname($pimcoreUser->getFirstname())
->setLastname($pimcoreUser->getLastname())
->setParent(Service::createFolderByPath(self::USER_FOLDER))
->setUsePimcoreUserPassword(true)
->setPublished(true)
->setKey(Service::getUniqueKey($portalUser))
->setPreferredLanguage($pimcoreUser->getLanguage());

$portalUser->save();
}

return $portalUser;
}
}

# add this to your container service definition
services:
AppBundle\EventListener\PortalEngineAuthenticationSubscriber:
tags:
- { name: kernel.event_subscriber }