providerRegister('default', DefaultIdentityProvider::class); } /** * Register an authentication provider */ public function providerRegister(string $identifier, string $class): void { $this->availableIdentityProviders[$identifier] = $class; } public function providerList(?array $filter = null): array { $requestedProviders = $filter ? $filter : array_keys($this->availableIdentityProviders); $result = []; foreach ($requestedProviders as $identifier) { // Check if provider is available if (!isset($this->availableIdentityProviders[$identifier])) { continue; } // Check cache first if (isset($this->cachedIdentityProviders[$identifier])) { $result[$identifier] = $this->cachedIdentityProviders[$identifier]; } else { // Instantiate the provider and cache it $providerClass = $this->availableIdentityProviders[$identifier]; try { // Server::get automatically detects context from calling object $providerInstance = Server::runtimeContainer()->get($providerClass); // Cache the instance $this->cachedIdentityProviders[$identifier] = $providerInstance; $result[$identifier] = $providerInstance; } catch (\Exception $e) { // Skip providers that can't be resolved error_log("Failed to resolve identity provider {$providerClass}: " . $e->getMessage()); continue; } } } return $result; } /** * Authenticate user against enabled providers */ public function authenticate(string $identity, string $credential): User | null { // validate identity and credential if (empty($identity) || empty($credential)) { return null; } // retrieve user by identity $user = $this->userService->fetchByIdentity($identity); // determine if user has logged in before if (!$user) { return null; } // determine if user has a identity provider assigned if ($user->getProvider() === null) { return null; } $authenticated = $this->authenticateExtant($user->getProvider(), $identity, $credential); if ($authenticated) { return $user; } return null; } public function authenticateExtant(string $provider, string $identity, string $credential): bool { // determine if provider is enabled $providers = $this->providerList([$provider]); if (empty($providers)) { return false; } // Get the first (and should be only) provider $provider = reset($providers); // authenticate user against provider $user = $provider->authenticate($identity, $credential); return $user; } public function validate(string $identifier): Bool { $data = $this->userService->fetchByIdentifier($identifier); if (!$data) { return false; } if ($data['enabled'] !== true) { return false; } if ($data['tid'] !== $this->tenant->identifier()) { return false; } return true; } }