Skip to content

Instantly share code, notes, and snippets.

@MLukman
Last active November 4, 2022 14:21
Show Gist options
  • Save MLukman/cd8671e505e202f8753fd4ae7c296f71 to your computer and use it in GitHub Desktop.
Save MLukman/cd8671e505e202f8753fd4ae7c296f71 to your computer and use it in GitHub Desktop.
Authenticator class to allow PimcoreLdapBundle (https://pimcore.com/en/developers/marketplace/blackbit_digital_commerce/pimcore-ldap_e48456) to work on Pimcore 10.5 and above
<?php
namespace App\Service;
use Alep\LdapBundle\Service\Ldap;
use Exception;
use Pimcore\Bundle\AdminBundle\Security\Authenticator\AdminAbstractAuthenticator;
use Pimcore\Bundle\AdminBundle\Security\User\User;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
/**
* Authenticator that utilizes PimcoreLdapBundle for admin logins using LDAP.
*
* To use:
* 1. Install and setup PimcoreLdapBundle first (refer https://github.com/BlackbitDigitalCommerce/pimcore-ldap-bundle).
* 2. Register this class as a service inside config/services.yaml:
*
* services:
* App\Service\LdapAdminAuthenticator:
* calls:
* - setLdapService: ['@?Alep\LdapBundle\Service\Ldap']
*
* 3. Add this class full name to the top of custom_authenticators inside config/packages/security.yaml:
*
* custom_authenticators:
* - App\Service\LdapAdminAuthenticator
* - Pimcore\Bundle\AdminBundle\Security\Authenticator\AdminLoginAuthenticator
* - Pimcore\Bundle\AdminBundle\Security\Authenticator\AdminTokenAuthenticator
* - Pimcore\Bundle\AdminBundle\Security\Authenticator\AdminSessionAuthenticator
*
* @author Muhammad Lukman Nasaruddin <lukman.nasaruddin@tm.com.my>
*/
class LdapAdminAuthenticator extends AdminAbstractAuthenticator
{
/**
* The regex for all logins that need to be authenticated by this authenticator
* Examples:
* - Uppercase alphabets followed by numbers = /^[[:upper:]]+[[:digit:]]+$/
*/
const LDAP_LOGINS_REGEX = '/^.+/';
/**
* Setting this to true will allow LDAP users to login using the last password
* when this authenticator is disabled/removed
*/
const ALLOW_FALLBACK_LOGIN = false;
protected ?Ldap $ldapService = null;
public function setLdapService(Ldap $ldapService)
{
$this->ldapService = $ldapService;
}
public function supports(Request $request): ?bool
{
return
$request->attributes->get('_route') === self::PIMCORE_ADMIN_LOGIN_CHECK &&
$request->getMethod() === 'POST' &&
$request->get('password') &&
($username = $request->get('username')) &&
\preg_match(static::LDAP_LOGINS_REGEX, $username) &&
$this->ldapService &&
!$this->ldapService->isUserExcluded($username);
}
public function authenticate(Request $request): Passport
{
try {
list($username, $password) = [$request->get('username'), $request->get('password')];
//authenticate via ldap
$ldapUser = $this->ldapService->authenticate($username, $password);
//Update Pimcore user
$pimcoreUser = $this->ldapService->updatePimcoreUser(
$username,
static::ALLOW_FALLBACK_LOGIN ? $password : bin2hex(rand()),
$ldapUser);
// Set session
$this->saveUserToSession(new User($pimcoreUser));
$passport = new SelfValidatingPassport(new UserBadge($username));
if (($csrfToken = $request->get('csrf_token'))) {
$passport->addBadge(new CsrfTokenBadge('pimcore_admin_authenticate', $csrfToken));
}
return $passport;
} catch (AuthenticationException $e) {
throw $e;
} catch (Exception $e) {
throw new CustomUserMessageAuthenticationException('Unable to connect to LDAP');
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment