config; if (empty($config)) { return ProviderResult::failed( ProviderResult::ERROR_INVALID_PROVIDER, 'OIDC provider configuration is missing' ); } try { $authData = $this->client->beginAuth($config, $callbackUrl, $returnUrl); return ProviderResult::redirect( $authData['redirect_url'], [ 'state' => $authData['state'], 'nonce' => $authData['nonce'] ?? null, 'return_url' => $returnUrl, ] ); } catch (\Throwable $e) { return ProviderResult::failed( ProviderResult::ERROR_INTERNAL, 'Failed to initiate OIDC authentication: ' . $e->getMessage() ); } } public function completeRedirect(ProviderContext $context, array $params): ProviderResult { $config = $context->config; $expectedState = $context->getMeta('state'); $expectedNonce = $context->getMeta('nonce'); if (empty($config)) { return ProviderResult::failed( ProviderResult::ERROR_INVALID_PROVIDER, 'OIDC provider configuration is missing' ); } if (empty($expectedState)) { return ProviderResult::failed( ProviderResult::ERROR_INVALID_CREDENTIALS, 'Missing expected state for OIDC verification' ); } try { $result = $this->client->completeAuth($params, $config, $expectedState, $expectedNonce); if (!$result || !isset($result['success']) || !$result['success']) { return ProviderResult::failed( ProviderResult::ERROR_INVALID_CREDENTIALS, $result['error'] ?? 'OIDC authentication failed' ); } return ProviderResult::success( [ 'provider' => $this->identifier(), 'subject' => $result['sub'] ?? null, 'email' => $result['email'] ?? null, 'name' => $result['name'] ?? null, 'attributes' => $result['attributes'] ?? [], ], [ 'return_url' => $context->getMeta('return_url'), ] ); } catch (\Throwable $e) { return ProviderResult::failed( ProviderResult::ERROR_INTERNAL, 'Failed to complete OIDC authentication: ' . $e->getMessage() ); } } // ========================================================================= // Attribute Helpers // ========================================================================= public function getAttributes(array $identity): array { return $identity['attributes'] ?? []; } public function mapAttributes(array $attributes, array $mapping): array { $mapped = []; foreach ($mapping as $sourceKey => $targetKey) { if (isset($attributes[$sourceKey])) { $mapped[$targetKey] = $attributes[$sourceKey]; } } return $mapped; } }