diff --git a/.env b/.env
index fa56934358a3961ae540d242d9f6ccf1aaaf80de..210a74a3bd82ded72dbb9e34f2ae2d98feab2fee 100644
--- a/.env
+++ b/.env
@@ -44,15 +44,14 @@ LOCK_DSN=semaphore
 CAMPUS_QR_URL=https://campusqr-dev.tugraz.at
 CAMPUS_QR_TOKEN=
 
-# LDAP
-LDAP_HOST=directory.tugraz.at
-LDAP_USER=cn=ldap_middleware,o=tug
-#LDAP_BASE_DN=ou=angehoerige,o=tug
-LDAP_BASE_DN=o=tug
-LDAP_PASS=
-
-LDAP_ATTRIBUTE_IDENTIFIER=cn
-LDAP_ATTRIBUTE_GIVEN_NAME=givenName
-LDAP_ATTRIBUTE_FAMILY_NAME=sn
-LDAP_ATTRIBUTE_EMAIL=mail
-LDAP_ATTRIBUTE_BIRTHDAY=DateOfBirth
+###> dbp/relay-base-person-connector-ldap-bundle ###
+LDAP_PERSON_PROVIDER_LDAP_HOST=directory.tugraz.at
+LDAP_PERSON_PROVIDER_LDAP_USERNAME=cn=ldap_middleware,o=tug
+LDAP_PERSON_PROVIDER_LDAP_BASE_DN=o=tug
+LDAP_PERSON_PROVIDER_LDAP_PASSWORD=
+LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_IDENTIFIER=cn
+LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_GIVEN_NAME=givenName
+LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_FAMILY_NAME=sn
+LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_EMAIL=mail
+LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_BIRTHDAY=DateOfBirth
+###< dbp/relay-base-person-connector-ldap-bundle ###
diff --git a/composer.json b/composer.json
index 1863d5b074519b07f99bf786d90ca50e18131257..81e192adffc0a7886aeca5af5fdc99516d8cc692 100644
--- a/composer.json
+++ b/composer.json
@@ -8,6 +8,7 @@
         "brainmaestro/composer-git-hooks": "^2.8",
         "dbp/relay-auth-bundle": "^0.1.3",
         "dbp/relay-base-person-bundle": "^0.1.3",
+        "dbp/relay-base-person-connector-ldap-bundle": "^0.2.0",
         "dbp/relay-checkin-bundle": "^1.0",
         "dbp/relay-core-bundle": "^0.1.10",
         "dbp/relay-frontend-bundle": "^0.1.0",
@@ -50,7 +51,8 @@
     "scripts": {
         "auto-scripts": {
             "cache:clear": "symfony-cmd",
-            "assets:install %PUBLIC_DIR%": "symfony-cmd"
+            "assets:install %PUBLIC_DIR%": "symfony-cmd",
+            "vendor/dbp/relay-core-bundle/bin/move-core-bundle.php": "php-script"
         },
         "post-install-cmd": [
             "@auto-scripts",
@@ -92,7 +94,11 @@
     "extra": {
         "symfony": {
             "allow-contrib": false,
-            "require": "^5.2"
+            "require": "^5.4",
+            "endpoint": [
+                "flex://defaults",
+                "https://api.github.com/repos/digital-blueprint/symfony-recipes/contents/index.json?ref=flex/main"
+            ]
         },
         "hooks": {
             "pre-commit": [
diff --git a/composer.lock b/composer.lock
index 8efcc8ebf4568463d86de799502b938248e26f57..ea20947a66f61f48666ab6cf512e9f005d2d3783 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "ee0c110c71982039155aad7aad3032f7",
+    "content-hash": "b39b09e46e43b66844ab9f708f402218",
     "packages": [
         {
             "name": "adldap2/adldap2",
@@ -464,6 +464,49 @@
             ],
             "time": "2021-10-27T09:05:38+00:00"
         },
+        {
+            "name": "dbp/relay-base-person-connector-ldap-bundle",
+            "version": "v0.2.1",
+            "source": {
+                "type": "git",
+                "url": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-base-person-connector-ldap-bundle.git",
+                "reference": "c0895118e1f57f21334e0cd205faa6d22a1b2739"
+            },
+            "require": {
+                "adldap2/adldap2": "^10.3",
+                "dbp/relay-auth-bundle": "^0.1.6",
+                "dbp/relay-base-person-bundle": "^0.1.5",
+                "ext-json": "*",
+                "ext-simplexml": "*",
+                "guzzlehttp/guzzle": "^7.3",
+                "league/uri": "^6.5",
+                "php": "^7.3 || ^8.0",
+                "symfony/event-dispatcher": "^5.4",
+                "symfony/framework-bundle": "^5.2"
+            },
+            "require-dev": {
+                "friendsofphp/php-cs-fixer": "^3.0",
+                "mockery/mockery": "^1.4",
+                "phpstan/phpstan": "^1.0.0",
+                "phpstan/phpstan-phpunit": "^1.0.0",
+                "symfony/browser-kit": "^5.2",
+                "symfony/http-client": "^5.2",
+                "symfony/monolog-bundle": "^3.7",
+                "symfony/phpunit-bridge": "^5.2",
+                "vimeo/psalm": "^4.2.1"
+            },
+            "type": "symfony-bundle",
+            "autoload": {
+                "psr-4": {
+                    "Dbp\\Relay\\BasePersonConnectorLdapBundle\\": "src/"
+                }
+            },
+            "notification-url": "https://packagist.org/downloads/",
+            "license": [
+                "AGPL-3.0-or-later"
+            ],
+            "time": "2022-01-31T15:47:43+00:00"
+        },
         {
             "name": "dbp/relay-checkin-bundle",
             "version": "v1.0.3",
@@ -10084,5 +10127,5 @@
     "platform-overrides": {
         "php": "7.3"
     },
-    "plugin-api-version": "2.2.0"
+    "plugin-api-version": "2.1.0"
 }
diff --git a/config/bundles.php b/config/bundles.php
index 210ae602cafd27468d37dfc0299805e13f1337c6..ac898149139312d9179e1cb992ee236f23fa3fa5 100644
--- a/config/bundles.php
+++ b/config/bundles.php
@@ -14,5 +14,6 @@ return [
     Dbp\Relay\BasePersonBundle\DbpRelayBasePersonBundle::class => ['all' => true],
     Dbp\Relay\FrontendBundle\DbpRelayFrontendBundle::class => ['all' => true],
     Dbp\Relay\CheckinBundle\DbpRelayCheckinBundle::class => ['all' => true],
+    Dbp\Relay\BasePersonConnectorLdapBundle\DbpRelayBasePersonConnectorLdapBundle::class => ['all' => true],
     Dbp\Relay\CoreBundle\DbpRelayCoreBundle::class => ['all' => true],
 ];
diff --git a/config/packages/dbp_relay_base_person_connector_ldap.yaml b/config/packages/dbp_relay_base_person_connector_ldap.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c310c395e35438a798ef2bbd9b0fe6f3ad4566de
--- /dev/null
+++ b/config/packages/dbp_relay_base_person_connector_ldap.yaml
@@ -0,0 +1,12 @@
+dbp_relay_base_person_connector_ldap:
+  ldap:
+    host: '%env(LDAP_PERSON_PROVIDER_LDAP_HOST)%'
+    base_dn: '%env(LDAP_PERSON_PROVIDER_LDAP_BASE_DN)%'
+    username: '%env(LDAP_PERSON_PROVIDER_LDAP_USERNAME)%'
+    password: '%env(LDAP_PERSON_PROVIDER_LDAP_PASSWORD)%'
+    attributes:
+      identifier: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_IDENTIFIER)%'
+      given_name: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_GIVEN_NAME)%'
+      family_name: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_FAMILY_NAME)%'
+      email: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_EMAIL)%'
+      birthday: '%env(LDAP_PERSON_PROVIDER_LDAP_ATTRIBUTE_BIRTHDAY)%'
diff --git a/config/services.yaml b/config/services.yaml
index 9eee590f63c438b44610040c540c8e9f21d61558..58251bf448000571f85ae9e99f4531f0d9e8bdfb 100644
--- a/config/services.yaml
+++ b/config/services.yaml
@@ -14,23 +14,6 @@ services:
       - '../src/Kernel.php'
       - '../src/Tests/'
 
-  Dbp\Relay\BasePersonBundle\API\PersonProviderInterface:
-    '@App\Service\LDAPPersonProvider'
-
-  Dbp\Relay\AuthBundle\API\UserRolesInterface:
-    '@App\Service\CustomUserRoles'
-
 parameters:
-  app.ldap.host: '%env(LDAP_HOST)%'
-  app.ldap.base_dn: '%env(LDAP_BASE_DN)%'
-  app.ldap.username: '%env(LDAP_USER)%'
-  app.ldap.password: '%env(LDAP_PASS)%'
-
-  app.ldap.attributes.identifier: '%env(LDAP_ATTRIBUTE_IDENTIFIER)%'
-  app.ldap.attributes.given_name: '%env(LDAP_ATTRIBUTE_GIVEN_NAME)%'
-  app.ldap.attributes.family_name: '%env(LDAP_ATTRIBUTE_FAMILY_NAME)%'
-  app.ldap.attributes.email: '%env(LDAP_ATTRIBUTE_EMAIL)%'
-  app.ldap.attributes.birthday: '%env(LDAP_ATTRIBUTE_BIRTHDAY)%'
-
   app.cache.person-cache-path: '%kernel.cache_dir%/dbp/app-auth-person'
   app.cache.ldap-cache-path: '%kernel.cache_dir%/dbp/app-ldap'
diff --git a/src/EventSubscriber/PersonFromUserItemSubscriber.php b/src/EventSubscriber/PersonFromUserItemSubscriber.php
new file mode 100644
index 0000000000000000000000000000000000000000..707449857c6d471635f91f572b11f71aabce1087
--- /dev/null
+++ b/src/EventSubscriber/PersonFromUserItemSubscriber.php
@@ -0,0 +1,28 @@
+<?php
+
+declare(strict_types=1);
+
+namespace App\EventSubscriber;
+
+use Dbp\Relay\BasePersonConnectorLdapBundle\Event\PersonFromUserItemPostEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class PersonFromUserItemSubscriber implements EventSubscriberInterface
+{
+    public static function getSubscribedEvents(): array
+    {
+        return [
+            PersonFromUserItemPostEvent::NAME => 'onPost',
+        ];
+    }
+
+    public function onPost(PersonFromUserItemPostEvent $event)
+    {
+        $person = $event->getPerson();
+
+        $roles = ['ROLE_SCOPE_LOCATION-CHECK-IN', 'ROLE_SCOPE_LOCATION-CHECK-IN-GUEST'];
+        $person->setExtraData('ldap-roles', $roles);
+
+        $event->setPerson($person);
+    }
+}
diff --git a/src/Service/CustomUserRoles.php b/src/Service/CustomUserRoles.php
deleted file mode 100644
index 81be6d516a0b2d2184b74b6753940fcd423325c1..0000000000000000000000000000000000000000
--- a/src/Service/CustomUserRoles.php
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace App\Service;
-
-use Dbp\Relay\AuthBundle\API\UserRolesInterface;
-
-class CustomUserRoles implements UserRolesInterface
-{
-    private $ldap;
-
-    public function __construct(LDAPApi $ldap)
-    {
-        $this->ldap = $ldap;
-    }
-
-    public function getRoles(?string $userIdentifier, array $scopes): array
-    {
-        // Convert all scopes to roles, like the default
-        $roles = [];
-        foreach ($scopes as $scope) {
-            $roles[] = 'ROLE_SCOPE_'.mb_strtoupper($scope);
-        }
-
-        // In case we have a real user also merge in roles from LDAP
-        if ($userIdentifier !== null) {
-            $personRoles = $this->ldap->getRolesForCurrentPerson();
-            $roles = array_merge($roles, $personRoles);
-            $roles = array_unique($roles);
-            sort($roles, SORT_STRING);
-        }
-
-        return $roles;
-    }
-}
diff --git a/src/Service/LDAPApi.php b/src/Service/LDAPApi.php
deleted file mode 100644
index 8d8828cb4c3b1d18d6d0f1852bcb2922341c7943..0000000000000000000000000000000000000000
--- a/src/Service/LDAPApi.php
+++ /dev/null
@@ -1,375 +0,0 @@
-<?php
-
-declare(strict_types=1);
-/**
- * LDAP wrapper service.
- *
- * @see https://github.com/Adldap2/Adldap2
- */
-
-namespace App\Service;
-
-use Adldap\Adldap;
-use Adldap\Connections\Provider;
-use Adldap\Connections\ProviderInterface;
-use Adldap\Models\User;
-use Adldap\Query\Builder;
-use Dbp\Relay\BasePersonBundle\Entity\Person;
-use Dbp\Relay\CoreBundle\API\UserSessionInterface;
-use Dbp\Relay\CoreBundle\Exception\ApiError;
-use Dbp\Relay\CoreBundle\Helpers\Tools as CoreTools;
-use Psr\Cache\CacheItemPoolInterface;
-use Psr\Container\ContainerInterface;
-use Psr\Log\LoggerAwareInterface;
-use Psr\Log\LoggerAwareTrait;
-use Symfony\Component\Cache\Adapter\FilesystemAdapter;
-use Symfony\Component\Cache\Psr16Cache;
-use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
-use Symfony\Component\HttpFoundation\Response;
-use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
-use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Symfony\Contracts\Service\ServiceSubscriberInterface;
-
-class LDAPApi implements LoggerAwareInterface, ServiceSubscriberInterface
-{
-    use LoggerAwareTrait;
-
-    private $PAGESIZE = 50;
-
-    /**
-     * @var Adldap
-     */
-    private $ad;
-
-    private $cachePool;
-
-    private $personCache;
-
-    private $cacheTTL;
-
-    /**
-     * @var Person|null
-     */
-    private $currentPerson;
-
-    private $providerConfig;
-
-    private $deploymentEnv;
-
-    private $locator;
-
-    private $params;
-
-    private $identifierAttributeName;
-
-    private $givenNameAttributeName;
-
-    private $familyNameAttributeName;
-
-    private $emailAttributeName;
-
-    private $birthdayAttributeName;
-
-    public function __construct(ContainerInterface $locator, ParameterBagInterface $params)
-    {
-        $this->ad = new Adldap();
-        $this->cacheTTL = 0;
-        $this->currentPerson = null;
-        $this->params = $params;
-        $this->providerConfig = [
-            'hosts' => [$this->params->get('app.ldap.host') ?? ''],
-            'base_dn' => $this->params->get('app.ldap.base_dn') ?? '',
-            'username' => $this->params->get('app.ldap.username') ?? '',
-            'password' => $this->params->get('app.ldap.password') ?? '',
-            'use_tls' => true,
-        ];
-        $this->locator = $locator;
-        $this->deploymentEnv = 'production';
-
-        $this->setPersonCache(new FilesystemAdapter('app-core-auth-person', 60, (string) $this->params->get('app.cache.person-cache-path')));
-        $this->setLDAPCache(new FilesystemAdapter('app-core-ldap', 360, (string) $this->params->get('app.cache.ldap-cache-path')), 360);
-
-        $this->identifierAttributeName = $this->params->get('app.ldap.attributes.identifier') ?? 'cn';
-        $this->givenNameAttributeName = $this->params->get('app.ldap.attributes.given_name') ?? 'givenName';
-        $this->familyNameAttributeName = $this->params->get('app.ldap.attributes.family_name') ?? 'sn';
-        $this->emailAttributeName = $this->params->get('app.ldap.attributes.email') ?? '';
-        $this->birthdayAttributeName = $this->params->get('app.ldap.attributes.birthday') ?? '';
-    }
-
-    public function setDeploymentEnvironment(string $env)
-    {
-        $this->deploymentEnv = $env;
-    }
-
-    public function setLDAPCache(?CacheItemPoolInterface $cachePool, int $ttl)
-    {
-        $this->cachePool = $cachePool;
-        $this->cacheTTL = $ttl;
-    }
-
-    public function setPersonCache(?CacheItemPoolInterface $cachePool)
-    {
-        $this->personCache = $cachePool;
-    }
-
-    private function getProvider(): ProviderInterface
-    {
-        if ($this->logger !== null) {
-            Adldap::setLogger($this->logger);
-        }
-        $ad = new Adldap();
-        $ad->addProvider($this->providerConfig);
-        $provider = $ad->connect();
-        assert($provider instanceof Provider);
-        if ($this->cachePool !== null) {
-            $provider->setCache(new Psr16Cache($this->cachePool));
-        }
-
-        return $provider;
-    }
-
-    private function getCachedBuilder(ProviderInterface $provider): Builder
-    {
-        // FIXME: https://github.com/Adldap2/Adldap2/issues/786
-        // return $provider->search()->cache($until=$this->cacheTTL);
-        // We depend on the default TTL of the cache for now...
-
-        /**
-         * @var Builder $builder
-         */
-        $builder = $provider->search()->cache();
-
-        return $builder;
-    }
-
-    private function getPeopleUserItems(array $filters): array
-    {
-        try {
-            $provider = $this->getProvider();
-            $builder = $this->getCachedBuilder($provider);
-
-            $search = $builder
-                ->where('objectClass', '=', $provider->getSchema()->person());
-
-            if (isset($filters['search'])) {
-                $items = explode(' ', $filters['search']);
-
-                // search for all substrings
-                foreach ($items as $item) {
-                    $search->whereContains('fullName', $item);
-                }
-            }
-
-            return $search->sortBy($this->familyNameAttributeName, 'asc')->paginate($this->PAGESIZE)->getResults();
-        } catch (\Adldap\Auth\BindException $e) {
-            // There was an issue binding / connecting to the server.
-            throw new ApiError(Response::HTTP_BAD_GATEWAY, sprintf('People could not be loaded! Message: %s', CoreTools::filterErrorMessage($e->getMessage())));
-        }
-    }
-
-    public function getPersons(array $filters): array
-    {
-        $persons = [];
-        $items = $this->getPeopleUserItems($filters);
-        foreach ($items as $item) {
-            $person = $this->personFromUserItem($item, false);
-            $persons[] = $person;
-        }
-
-        return $persons;
-    }
-
-    /**
-     * @return Person[]
-     */
-    public function getPersonsByNameAndBirthDate(string $givenName, string $familyName, string $birthDate): array
-    {
-        if ($this->birthdayAttributeName === '') {
-            return [];
-        }
-
-        try {
-            $provider = $this->getProvider();
-            $builder = $this->getCachedBuilder($provider);
-
-            /** @var User[] $users */
-            $users = $builder
-                ->where('objectClass', '=', $provider->getSchema()->person())
-                ->whereEquals($this->givenNameAttributeName, $givenName)
-                ->whereEquals($this->familyNameAttributeName, $familyName)
-                ->whereEquals($this->birthdayAttributeName, $birthDate) // (e.g. 1981-07-18)
-                ->sortBy($this->familyNameAttributeName, 'asc')->paginate($this->PAGESIZE)->getResults();
-
-            $people = [];
-
-            foreach ($users as $user) {
-                $people[] = $this->personFromUserItem($user, true);
-            }
-
-            return $people;
-        } catch (\Adldap\Auth\BindException $e) {
-            // There was an issue binding / connecting to the server.
-            throw new ApiError(Response::HTTP_BAD_GATEWAY, sprintf('Persons could not be loaded! Message: %s', CoreTools::filterErrorMessage($e->getMessage())));
-        }
-    }
-
-    public function getPersonUserItem(string $identifier): ?User
-    {
-        try {
-            $provider = $this->getProvider();
-            $builder = $this->getCachedBuilder($provider);
-
-            /** @var User $user */
-            $user = $builder
-                ->where('objectClass', '=', $provider->getSchema()->person())
-                ->whereEquals($this->identifierAttributeName, $identifier)
-                ->first();
-
-            if ($user === null) {
-                throw new NotFoundHttpException(sprintf("Person with id '%s' could not be found!", $identifier));
-            }
-
-            return $user;
-        } catch (\Adldap\Auth\BindException $e) {
-            // There was an issue binding / connecting to the server.
-            throw new ApiError(Response::HTTP_BAD_GATEWAY, sprintf("Person with id '%s' could not be loaded! Message: %s", $identifier, CoreTools::filterErrorMessage($e->getMessage())));
-        }
-    }
-
-    public function personFromUserItem(User $user, bool $full): Person
-    {
-        $identifier = $user->getFirstAttribute($this->identifierAttributeName);
-
-        $person = new Person();
-        $person->setIdentifier($identifier);
-        $person->setGivenName($user->getFirstAttribute($this->givenNameAttributeName));
-        $person->setFamilyName($user->getFirstAttribute($this->familyNameAttributeName));
-
-        if ($this->emailAttributeName !== '') {
-            $person->setEmail($user->getFirstAttribute($this->emailAttributeName));
-        }
-
-        $birthDateString = $this->birthdayAttributeName !== '' ?
-            trim($user->getFirstAttribute($this->birthdayAttributeName) ?? '') : '';
-
-        if ($birthDateString !== '') {
-            $matches = [];
-
-            if (preg_match('/^(\d{4})-(\d{2})-(\d{2})$/', $birthDateString, $matches)) {
-                $person->setBirthDate("{$matches[1]}-{$matches[2]}-{$matches[3]}");
-            }
-        }
-
-        // TODO: Add code to decide what roles a user has (or just depend on the roles from CustomUserRoles)
-        $roles = ['ROLE_SCOPE_LOCATION-CHECK-IN', 'ROLE_SCOPE_LOCATION-CHECK-IN-GUEST'];
-        $person->setExtraData('ldap-roles', $roles);
-
-        return $person;
-    }
-
-    public function getRolesForCurrentPerson(): array
-    {
-        $person = $this->getCurrentPerson();
-        if ($person !== null) {
-            $roles = $person->getExtraData('ldap-roles');
-            assert(is_array($roles));
-
-            return $roles;
-        }
-
-        return [];
-    }
-
-    public function getPerson(string $id): Person
-    {
-        $id = str_replace('/people/', '', $id);
-
-        $session = $this->getUserSession();
-        $currentIdentifier = $session->getUserIdentifier();
-
-        if ($currentIdentifier !== null && $currentIdentifier === $id) {
-            // fast path: getCurrentPerson() does some caching
-            $person = $this->getCurrentPerson();
-            assert($person !== null);
-        } else {
-            $user = $this->getPersonUserItem($id);
-            $person = $this->personFromUserItem($user, true);
-        }
-
-        return $person;
-    }
-
-    public function getPersonForExternalService(string $service, string $serviceID): Person
-    {
-        throw new BadRequestHttpException("Unknown service: $service");
-    }
-
-    private function getUserSession(): UserSessionInterface
-    {
-        return $this->locator->get(UserSessionInterface::class);
-    }
-
-    public function getCurrentPersonCached(): Person
-    {
-        $session = $this->getUserSession();
-        $currentIdentifier = $session->getUserIdentifier();
-        assert($currentIdentifier !== null);
-
-        $cache = $this->personCache;
-        $cacheKey = $session->getSessionCacheKey().'-'.$currentIdentifier;
-        // make sure the cache is longer than the session, so just double it.
-        $cacheTTL = $session->getSessionTTL() * 2;
-
-        $item = $cache->getItem($cacheKey);
-
-        if ($item->isHit()) {
-            $person = $item->get();
-            if ($person === null) {
-                throw new NotFoundHttpException();
-            }
-
-            return $person;
-        } else {
-            try {
-                $user = $this->getPersonUserItem($currentIdentifier);
-                $person = $this->personFromUserItem($user, true);
-            } catch (NotFoundHttpException $e) {
-                $person = null;
-            }
-            $item->set($person);
-            $item->expiresAfter($cacheTTL);
-            $cache->save($item);
-            if ($person === null) {
-                throw new NotFoundHttpException();
-            }
-
-            return $person;
-        }
-    }
-
-    public function getCurrentPerson(): ?Person
-    {
-        $session = $this->getUserSession();
-        $currentIdentifier = $session->getUserIdentifier();
-        if ($currentIdentifier === null) {
-            return null;
-        }
-
-        if ($this->currentPerson !== null && $this->currentPerson->getIdentifier() !== $currentIdentifier) {
-            $this->currentPerson = null;
-        }
-
-        if ($this->currentPerson === null) {
-            $this->currentPerson = $this->getCurrentPersonCached();
-        }
-
-        return $this->currentPerson;
-    }
-
-    public static function getSubscribedServices()
-    {
-        return [
-            UserSessionInterface::class,
-        ];
-    }
-}
diff --git a/src/Service/LDAPPersonProvider.php b/src/Service/LDAPPersonProvider.php
deleted file mode 100644
index 0bcdf7157b2802e24d95791f6dab04846f209971..0000000000000000000000000000000000000000
--- a/src/Service/LDAPPersonProvider.php
+++ /dev/null
@@ -1,43 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace App\Service;
-
-use Dbp\Relay\BasePersonBundle\API\PersonProviderInterface;
-use Dbp\Relay\BasePersonBundle\Entity\Person;
-
-class LDAPPersonProvider implements PersonProviderInterface
-{
-    private $ldapApi;
-
-    public function __construct(LDAPApi $ldapApi)
-    {
-        $this->ldapApi = $ldapApi;
-    }
-
-    public function getPersons(array $filters): array
-    {
-        return $this->ldapApi->getPersons($filters);
-    }
-
-    public function getPersonsByNameAndBirthDate(string $givenName, string $familyName, string $birthDate): array
-    {
-        return $this->ldapApi->getPersonsByNameAndBirthDate($givenName, $familyName, $birthDate);
-    }
-
-    public function getPerson(string $id): Person
-    {
-        return $this->ldapApi->getPerson($id);
-    }
-
-    public function getPersonForExternalService(string $service, string $serviceID): Person
-    {
-        return $this->ldapApi->getPersonForExternalService($service, $serviceID);
-    }
-
-    public function getCurrentPerson(): ?Person
-    {
-        return $this->ldapApi->getCurrentPerson();
-    }
-}
diff --git a/symfony.lock b/symfony.lock
index 66ecb613e17e8ba5cd89f26b0155f71e41ac4d8b..5e3fb14259279efdc00f065604e948d381011334 100644
--- a/symfony.lock
+++ b/symfony.lock
@@ -43,6 +43,9 @@
     "dbp/relay-base-person-bundle": {
         "version": "v0.1.3"
     },
+    "dbp/relay-base-person-connector-ldap-bundle": {
+        "version": "v0.2.0"
+    },
     "dbp/relay-checkin-bundle": {
         "version": "v1.0.2"
     },
@@ -462,6 +465,9 @@
     "symfony/polyfill-php81": {
         "version": "v1.23.0"
     },
+    "symfony/polyfill-uuid": {
+        "version": "v1.24.0"
+    },
     "symfony/process": {
         "version": "v4.4.16"
     },
@@ -547,6 +553,9 @@
             "templates/base.html.twig"
         ]
     },
+    "symfony/uid": {
+        "version": "v5.4.3"
+    },
     "symfony/validator": {
         "version": "4.3",
         "recipe": {